Types de types TypeScript — Les plus importantes à retenir (et les autres)
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.
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 utile | Ce que fait la balise | Fréquence d'utilisation | Cas d'usage principal |
|---|---|---|---|
Partial<T> | Toutes les propriétés deviennent optionnelles | Hebdomadaire | Mises à jour au format PATCH |
Required<T> | Toutes les propriétés optionnelles deviennent obligatoires | Mensuel | Signal de validation postérieure « c'est complet » |
Pick<T, K> | Conserve uniquement les propriétés nommées | Hebdomadaire | Formes d'API publiques, modèles de vue |
Omit<T, K> | Élimine les propriétés nommées | Hebdomadaire | Élimination de champs sensibles ou peu pertinents |
Record<K, V> | Objet avec des clés de type K et des valeurs de type V | Hebdomadaire | Dictionnaires typés avec vérification d'exhaustivité |
ReturnType<F> | Extrait le type de retour d'une fonction | Hebdomadaire (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 tuple | Occasionnel | Fonctions wrappers, mocks typés |
Awaited<T> | Déballage récursif des types Promise | Occasionnel | Obtention 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.
Installez nos extensions
Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide
恵 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 !
Outils essentiels
Tout voir Nouveautés
Tout voirMise à jour: Notre dernier outil a été ajouté le 17 juin 2026
