0Pricing
TypeScript Academy · Lezione

Inferire la forma dei risultati delle query

Lasci che il query builder inferisca il tipo della riga restituita.

Inferire la forma dei risultati delle query è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento TypeScript Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso TypeScript Academy include 4 lezioni in totale.

Il tipo del risultato segue la selezione

Un ottimo query builder non si limita a convalidare l'input: inferisce la forma esatta di ogni riga del risultato a partire dalle colonne selezionate. Selezioni meno colonne e il tipo del risultato si restringe.

Select dell'intera riga

La chiamata a select() senza proiezione restituisce l'intero tipo della riga.

const rows = await db.select().from(users);
// rows: { id: number; name: string; age: number | null; isAdmin: boolean }[]

Una select parziale restringe il tipo

Proietti solo le colonne necessarie e il tipo del risultato conterrà solo quelle chiavi.

const rows = await db
  .select({ id: users.id, name: users.name })
  .from(users);
// rows: { id: number; name: string }[]
// Accessing rows[0].age is a compile error.

Rinominare le colonne nel risultato

Le chiavi dell'oggetto select diventano le chiavi del risultato, quindi può rinominarle liberamente e il tipo rifletterà i nuovi nomi.

const rows = await db
  .select({ userId: users.id, fullName: users.name })
  .from(users);
// rows: { userId: number; fullName: string }[]

Colonne calcolate e aggregate

Le funzioni aggregate hanno un proprio tipo inferito. count() restituisce un numero; la chiave alias assegna il nome al risultato.

import { count } from "drizzle-orm";

const rows = await db
  .select({ total: count() })
  .from(users);
// rows: { total: number }[]

La nullabilità viene mantenuta

Se seleziona una colonna nullable, la sua nullabilità viene preservata nel risultato. Selezionare age mantiene il tipo number | null.

const rows = await db.select({ age: users.age }).from(users);
// rows: { age: number | null }[]

Come viene costruita l'inferenza

Il tipo del risultato è un mapped type sull'oggetto select: ogni valore è una colonna il cui tipo data (e la cui nullabilità) viene estratto nella chiave corrispondente.

type InferSelect<S> = {
  [K in keyof S]: S[K] extends Column<infer D, infer Null>
    ? Null extends true ? D | null : D
    : never;
};

Helper per una singola riga

Alcuni builder offrono un accesso tramite .get() o [0]. Il tipo dell'elemento viene comunque derivato dalla stessa selezione, semplicemente rimuovendo il livello dell'array.

const one = (await db.select({ id: users.id }).from(users))[0];
// one: { id: number } | undefined

Le join estendono la forma

Quando esegue una join, il tipo del risultato acquisisce le chiavi della tabella collegata. Le select parziali su più tabelle collegate continuano a restringere il tipo con precisione. (Le join sono trattate in una lezione dedicata.)

const rows = await db
  .select({ name: users.name, title: posts.title })
  .from(users)
  .innerJoin(posts, eq(posts.authorId, users.id));
// rows: { name: string; title: string }[]

Perché il restringimento è importante

Restituire solo le chiavi selezionate impedisce di dipendere accidentalmente da colonne che non sono state recuperate. Il tipo rispecchia l'SQL effettivo, quindi i bug dovuti a un recupero eccessivo o insufficiente dei dati emergono nell'editor.

Problema: espandere e poi selezionare

Se recupera l'intera riga e poi seleziona manualmente le chiavi in JS, perde il vantaggio del restringimento a livello di database e invia colonne extra sulla rete. È preferibile restringere già nella query.

Verifica rapida

Confermi la Sua comprensione delle forme inferite dei risultati.

Riepilogo

Il tipo del risultato viene calcolato a partire dalla selezione tramite un mapped type: le select complete restituiscono l'intera riga, quelle parziali si restringono alle chiavi scelte, i rinomini modificano le chiavi del risultato, la nullabilità viene mantenuta e le funzioni aggregate hanno i propri tipi. Il tipo statico rispecchia sempre l'SQL effettivamente scritto.

Domande Frequenti

La lezione «Inferire la forma dei risultati delle query» è gratuita?

Sì — il testo completo di «Inferire la forma dei risultati delle query» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso TypeScript Academy, passa a CoddyKit PRO. Il corso TypeScript Academy include 4 lezioni in totale.

Cosa imparerò in «Inferire la forma dei risultati delle query»?

Lasci che il query builder inferisca il tipo della riga restituita. Eserciti TypeScript Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare TypeScript Academy?

Non è richiesta alcuna esperienza precedente. TypeScript Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Inferire la forma dei risultati delle query»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione TypeScript Academy?

Sì. Ogni lezione TypeScript Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Mappatura da schema a tipo
  2. Costruzione di query type-safe
  3. Inferire la forma dei risultati delle query
  4. Relazioni e join con i tipi
← Torna a TypeScript Academy