Les pubs vous déplaisent ? Aller Sans pub Auj.

Types de types TypeScript — Les plus importantes à retenir (et les autres)

Mis à jour le

Partiel, Sélectionner, Omettre, Enregistrer, ReturnType, Paramètres, Awaited — huit types utiles avec des exemples avant et après et une analyse honnête sur lesquels vous les utiliserez chaque semaine.

Types utiles de TypeScript — Les uns à retenir (et les autres) 1
ANNONCE · Supprimer ?

Vous avez probablement lu une page de documentation TypeScript qui liste 20+ types utiles dans l'ordre alphabétique, définis chacun en une phrase, et vous a laissé hésitant sur lesquels il faut vraiment internaliser et lesquels existent pour les développeurs travaillant sur les internals des frameworks. Voici une version plus honnête : huit types, avec des exemples concrets avant et après, et une réponse directe sur leur utilisation quotidienne versus leur utilité occasionnelle.

Si vous commencez à partir de JSON brut et n'avez pas encore écrit vos interfaces, alors le convertisseur JSON en TypeScript vous permet d'obtenir une interface de base en quelques secondes — puis revenez ici pour ajouter ces types utiles.

Partial — Utilisation hebdomadaire. Apprenez-le en premier.

Fait de chaque propriété de T optionnelle. Le cas d'usage typique est les mises à jour au format PATCH, où vous envoyez uniquement les champs qui ont changé.

// Before: manually duplicating the interface with optional versions of everything
interface UserUpdate {
  name?: string;
  email?: string;
  age?: number;
}

// After: Partial derives it from the source of truth
interface User {
  name: string;
  email: string;
  age: number;
}

function updateUser(id: string, updates: Partial<User>) {
  // updates.name is string | undefined — TypeScript knows
}

Le problème avec la version « avant » : si vous ajoutez un champ à User, vous devez vous souvenir d'ajouter ce champ à UserUpdate aussi. Avec Partial<User>, l'ajout d'un champ dans l'interface source le rend automatiquement disponible dans les mises à jour. Les types restent synchronisés.

Required — Utilisation mensuelle, mais vous épargne dans une situation spécifique.

L'inverse de Partial — retire toutes les ? d'un type. Le cas d'usage le plus utile est après une validation : vous recevez un objet de configuration de type loose, vous vérifiez que tous les champs sont présents, puis vous souhaitez que TypeScript cesse de suggérer que tout peut être indéfini.

// Before: after validating, you still fight undefined checks everywhere
interface Config {
  apiUrl?: string;
  timeout?: number;
  retries?: number;
}

function initApp(config: Config) {
  config.apiUrl?.trim(); // need optional chaining even after checking
}

// After: Required signals "this has been validated, stop warning me"
function validateAndInit(raw: Config): void {
  if (!raw.apiUrl) throw new Error("apiUrl required");
  if (!raw.timeout) throw new Error("timeout required");
  if (!raw.retries) throw new Error("retries required");

  const config = raw as Required<Config>;
  config.apiUrl.trim(); // no optional chaining needed
}

Remarque honnête : Required<T> ne fait pas de validation en temps réel — vous devez toujours écrire les vérifications. Il change simplement ce que TypeScript croit à l'étape suivante. Utilisez-le pour communiquer « cela a été validé » au niveau des types.

Pick — Utilisation hebdomadaire. Nommez ce que vous voulez.

Crée un nouveau type contenant uniquement les propriétés que vous nommez dans T. Utile lorsque vous souhaitez un sous-ensemble d'une interface plus grande — des formes d'API publiques, des modèles de vue, des réponses sérialisées.

// Before: manually maintaining a separate interface that drifts from User
interface UserPublicProfile {
  name: string;
  bio: string;
  avatarUrl: string;
}

// After: Pick stays in sync with the source
interface User {
  id: string;
  name: string;
  email: string;       // private — shouldn't go to clients
  passwordHash: string;  // definitely private
  bio: string;
  avatarUrl: string;
}

type UserPublicProfile = Pick<User, "name" | "bio" | "avatarUrl">;

Pick est l'outil approprié lorsque la liste des propriétés que vous voulez est plus courte que la liste que vous auriez besoin de exclude. Quand le sens est inverse, optez pour Omit.

Omit — Utilisation hebdomadaire. Nommez ce que vous ne voulez pas.

Complément de Pick — crée un type contenant toutes les propriétés de T sauf celles que vous nommez. Quand vous avez une grande interface et seulement quelques champs à exclure, Omit rend l'intention plus claire que de lister tout ce que vous voulez inclure.

// Before: manually listing every field except the sensitive ones
// Easy to miss a new field added to User later
interface UserForClient {
  id: string;
  name: string;
  email: string;
  bio: string;
  avatarUrl: string;
  // passwordHash intentionally omitted — but a future dev might not know that
}

// After: Omit states the exclusion explicitly
type UserForClient = Omit<User, "passwordHash">;
// If User gains a new "address" field, UserForClient gets it automatically

Une chose que ni Pick ni Omit ne font : changer le type des propriétés individuelles. Si vous souhaitez sélectionner des champs et et transformer leurs types, vous êtes en train de chercher un type mappé, qui est un outil entièrement différent.

Record — Utilisation hebdomadaire. Le dictionnaire typé.

Crée un type d'objet où toutes les clés sont de type K et toutes les valeurs sont de type V. Le vrai gain vient quand K est un type de union — TypeScript signale une erreur si vous manquez une clé. Les signatures d'index génériques acceptent silencieusement des objets incomplets ; Record avec une clé de union ne le fait pas.

// Before: index signature with no exhaustiveness checking
const rolePermissions: { [key: string]: string[] } = {
  admin: ["read", "write", "delete"],
  editor: ["read", "write"],
  // forgot "viewer" — TypeScript doesn't notice
};

// After: Record with a union key enforces completeness
type Role = "admin" | "editor" | "viewer";

const rolePermissions: Record<Role, string[]> = {
  admin: ["read", "write", "delete"],
  editor: ["read", "write"],
  viewer: ["read"],
  // TypeScript error if any Role is missing
  // TypeScript error if you try to add an unknown key
};

Le contrôle d'exhaustivité est le vrai gain. Cela importe quand les clés représentent quelque chose de significatif, comme des rôles, des types d'événements, des méthodes HTTP ou des codes d'état — tout ce qui où une absence de cas est une erreur, et non simplement une omission.

ReturnType — Utilisation hebdomadaire si vous consommez des fonctions tierces.

Extrait le type de retour d'une fonction. Le cas d'usage le plus utile est de typage une variable qui contient le résultat d'une fonction d'une bibliothèque — sans avoir à importer séparément le type de retour (ce que les bibliothèques ne exportent pas toujours de manière claire).

// Before: manually annotating the return type — it can drift
function getCurrentUser() {
  return { id: "u1", name: "Alice", roles: ["admin"] as const };
}

let cachedUser: { id: string; name: string; roles: readonly string[] };
// If getCurrentUser's return changes, this annotation doesn't update automatically

// After: ReturnType derives it and keeps in sync
type CurrentUser = ReturnType<typeof getCurrentUser>;
let cachedUser: CurrentUser;

// Especially useful with unexported library types:
import { useQuery } from "@tanstack/react-query";
type QueryResult = ReturnType<typeof useQuery>;
// No need to figure out what QueryObserverResult<...> looks like or import it

Parameters — Utilisation occasionnelle. Principalement pour les wrappers.

Extrait les types de paramètres d'une fonction sous forme de tuple. Vue honnête : vous n'allez pas l'utiliser hebdomadairement sauf si vous écrivez beaucoup de fonctions wrappers ou d'utilitaires d'ordre supérieur. Mais quand vous en avez besoin, il n'existe pas d'alternative propre.

// Before: manually duplicating parameter types in the wrapper
function createEvent(
  type: string,
  payload: Record<string, unknown>,
  timestamp: number
) { /* ... */ }

// Every time createEvent changes, this wrapper needs a manual update:
function loggedCreateEvent(
  type: string,
  payload: Record<string, unknown>,
  timestamp: number
) {
  console.log("Creating event:", type);
  return createEvent(type, payload, timestamp);
}

// After: Parameters keeps the wrapper in sync automatically
function loggedCreateEvent(...args: Parameters<typeof createEvent>) {
  console.log("Creating event:", args[0]);
  return createEvent(...args);
}

Le patron de diffusion + reste (...args: Parameters<F>) est l'idiome principal. Il apparaît aussi dans les mocks de tests : jest.fn<ReturnType<F>, Parameters<F>>() vous donne un mock complètement typé sans avoir à importer séparément la signature de la fonction.

Awaited — Utilisez-le lorsque vous devez déballer les types de Promise sans les appeler.

Ajouté dans TypeScript 4.5 (sorti en novembre 2021). Déballage récursif de Promise<T> pour atteindre T. Avant son existence, obtenir le type résolu d'une fonction asynchrone signifiait écrire un type conditionnel : ReturnType<F> extends Promise<infer U> ? U : never — qui échoue sur des promesses doublement enveloppées et est difficile à lire dans les différences.

// Before: conditional type to unwrap — breaks on nested Promises
async function fetchUser(id: string) {
  const res = await fetch(`/api/users/${id}`);
  return res.json() as { id: string; name: string; email: string };
}

type FetchedUser =
  ReturnType<typeof fetchUser> extends Promise<infer U> ? U : never;
// Works for Promise<T> but not Promise<Promise<T>>

// After: Awaited handles both cases cleanly
type FetchedUser = Awaited<ReturnType<typeof fetchUser>>;

// Awaited recursively unwraps:
type A = Awaited<Promise<string>>;            // string
type B = Awaited<Promise<Promise<string>>>;  // string
type C = Awaited<string>;                      // string (no-op on non-Promise)

La combinaison Awaited<ReturnType<typeof fn>> vaut la peine d'être mémorisée comme unité — elle couvre 90% d'extraction de types asynchrones dans le code d'application.

Fiche de révision

Type utileCe que fait la baliseFréquence d'utilisationCas d'usage principal
Partial<T>Toutes les propriétés deviennent optionnellesHebdomadaireMises à jour au format PATCH
Required<T>Toutes les propriétés optionnelles deviennent obligatoiresMensuelSignal de validation postérieure « c'est complet »
Pick<T, K>Conserve uniquement les propriétés nomméesHebdomadaireFormes d'API publiques, modèles de vue
Omit<T, K>Élimine les propriétés nomméesHebdomadaireÉlimination de champs sensibles ou peu pertinents
Record<K, V>Objet avec des clés de type K et des valeurs de type VHebdomadaireDictionnaires typés avec vérification d'exhaustivité
ReturnType<F>Extrait le type de retour d'une fonctionHebdomadaire (surtout avec des bibliothèques)Typage d'une variable à partir d'un type inféré ou non exporté
Parameters<F>Extrait les types de paramètres d'une fonction sous forme de tupleOccasionnelFonctions wrappers, mocks typés
Awaited<T>Déballage récursif des types PromiseOccasionnelObtention du type résolu d'une fonction asynchrone

Les uns qui ne sont pas sur cette liste

TypeScript fournit également Readonly<T>, NonNullable<T>, Extract<T,U>, Exclude<T,U>, InstanceType<C>, ConstructorParameters<C>et plusieurs types littéraux. Ils sont réels et utiles occasionnellement, mais ils apparaissent dans le code des bibliothèques, des outils génériques et de la programmation de niveau de type — pas dans le code d'application typique. Si vous avez appris les huit ci-dessus, consultez les autres quand vous en avez vraiment besoin.

Le principe sous-jacent est le même pour tous : décrire une transformation d'un type existant plutôt que de le dupliquer. Les noms spécifiques des types utiles sont simplement une vocabulaire pour exprimer cette intention à TypeScript.

Envie d'une expérience sans pub ? Passez à la version sans pub

Installez nos extensions

Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide

Sur Extension Chrome Sur Extension de bord Sur Extension Firefox Sur Extension de l'opéra

Le Tableau de Bord Est Arrivé !

Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !

ANNONCE · Supprimer ?
ANNONCE · Supprimer ?
ANNONCE · Supprimer ?

Coin des nouvelles avec points forts techniques

Impliquez-vous

Aidez-nous à continuer à fournir des outils gratuits et précieux

Offre-moi un café
ANNONCE · Supprimer ?