Introduction : Pourquoi avez-vous besoin des clés d'interface sous forme de tableau ?
Imaginez : vous travaillez sur un grand projet en TypeScript et vous devez parcourir tous les champs d'un objet complexe, créer un formulaire dynamique avec React, filtrer des données ou simplement afficher la liste des propriétés disponibles. Le problème est que TypeScript est une surcouche de JavaScript, et ses types n'existent que pendant la compilation. À l'exécution, ils disparaissent. Que faire ? Comment obtenir les clés d'une interface TypeScript sous forme de tableau de chaînes pour les utiliser dans du code réel ?
Une question qui hante des milliers de développeurs sur Stack Overflow. Aujourd'hui, en 2025, nous allons analyser toutes les approches possibles : des plus simples et fiables aux plus avancées. Vous apprendrez à faire travailler TypeScript pour vous, et non contre vous. C'est parti !
Le problème : Les types "disparaissants"
Regardons tout de suite la racine du problème. Supposons que vous ayez cette interface :
interface User { id: number; name: string; email: string; isAdmin: boolean;}Vous devez obtenir un tableau de chaînes : ['id', 'name', 'email', 'isAdmin']. La première idée qui vient à l'esprit est d'utiliser Object.keys(). Mais il y a un hic. Si vous essayez d'écrire ceci :
const keys = Object.keys({} as User);// Type : string[]TypeScript vous retournera le type string[], et non ('id' | 'name' | 'email' | 'isAdmin')[]. C'est inutile — vous perdez toute information sur les clés spécifiques.
Pourquoi cela se produit-il ? Parce que Object.keys() en JavaScript retourne toujours un tableau de chaînes. TypeScript ne peut pas savoir avec certitude quelles seront les clés de l'objet lors de l'exécution (par exemple, si l'objet est étendu). Il donne donc le type le plus sûr, mais inutile.
Solution 1 : Tableau "manuel" (Simplicité et sécurité)
La méthode la plus simple et recommandée dans 90% des cas est de créer le tableau manuellement et d'en déduire le type. Ce n'est pas une blague. Cette approche garantit que votre tableau sera toujours synchronisé avec l'interface.
// 1. Définir le tableau de clésexport const USER_KEYS = ['id', 'name', 'email', 'isAdmin'] as const;
// 2. Déduire le type du tableautype UserKey = typeof USER_KEYS[number]; // 'id' | 'name' | 'email' | 'isAdmin'
// 3. Utiliser pour l'interfaceinterface User { [key in UserKey]: key extends 'id' ? number : key extends 'name' ? string : key extends 'email' ? string : boolean;}
// 4. Obtenir le tableau de chaînesconst keys: string[] = [...USER_KEYS];console.log(keys); // ['id', 'name', 'email', 'isAdmin']Avantages : Typage complet, pas d'astuces magiques, facile à lire et à maintenir.
Inconvénients : Nécessite de maintenir deux endroits (interface et tableau) manuellement.
Solution 2 : Type utilitaire avec keyof (Avancé, mais avec des réserves)
TypeScript fournit l'opérateur keyof, qui retourne une union de clés (union type). Mais comment transformer cette union en tableau de chaînes ? En 2025, cela nécessite encore une petite astuce.
La méthode classique consiste à utiliser une fonction auxiliaire qui vérifie les types lors de la compilation :
// Fonction auxiliairefunction getKeys<T>(obj: T): (keyof T)[] { return Object.keys(obj) as (keyof T)[];}
// Utilisationinterface Product { title: string; price: number; inStock: boolean;}
const product: Product = { title: 'Keyboard', price: 100, inStock: true};
const productKeys = getKeys(product);// Type : ("title" | "price" | "inStock")[]console.log(productKeys); // ['title', 'price', 'inStock']Important : Cette méthode fonctionne uniquement si vous avez un objet réel correspondant à l'interface. Si vous n'avez que l'interface, mais pas d'objet, vous devrez créer