Vous connaissez ce moment où le recruteur écrit « besoin de connaissances de base en TypeScript », et lors de l'entretien, ils posent des questions sur la covariance et la contre-variance ? Oui, oui, nous sommes tous passés par là. Il est temps de comprendre ce qu'ils demandent réellement lors des entretiens TypeScript et comment répondre de manière à ressembler à une personne qui a lu non seulement la documentation, mais aussi les sources du compilateur (spoiler : pas nécessairement).
Allons analyser les questions les plus populaires qu'ils aiment poser lors des entretiens. Mais pas seulement « qu'est-ce qu'une interface », mais avec des situations réelles et des explications sur les raisons pour lesquelles cela dérange quelqu'un.

1. « Quelle est la différence entre interface et type ? »
Niveau de difficulté : Cela semble simple jusqu'à ce que vous commenciez à répondre
C'est comme la question « quelle est la différence entre une pizza et des pâtes » : les deux sont à base de pâte, les deux sont italiens, mais le service est différent.
Réponse courte pour les impatients :
interface– pour les objets, extensible, peut être déclaré plusieurs fois (declaration merging)type– pour tout le reste, y compris union, intersection, primitives
Réponse détaillée pour l'impression :
// Interface aime l'héritage et l'addition
interface User {
name: string;
}
interface User {
age: number; // Se combine avec le précédent !
}
// Type est un alias, il ne peut pas être redéfini
type Product = {
id: number;
}
// type Product = { ... } // ❌ Erreur !
// Mais type sait faire des trucs cool :
type Status = 'pending' | 'success' | 'error';
type Response<T> = { data: T } | { error: string };Que dire à l'entretien : "En pratique, j'utilise interface pour décrire les structures de données qui peuvent être étendues (par exemple, les types d'API) et type pour les types d'union, les utilitaires et les constructions plus complexes. L'interface est meilleure pour les objets grâce à la fusion des déclarations. "
2. « Que sont les génériques et pourquoi en a-t-on besoin ? »
Niveau de difficulté : Cela semble effrayant, mais en réalité, c'est logique
Les génériques sont comme un modèle dans Word. Une fois écrit, remplacez toutes les données.
// Sans Generic - douleur et souffrance
function getFirstElementString(arr: string[]): string {
return arr[0];
}
function getFirstElementNumber(arr: number[]): number {
return arr[0];
}
// Avec Generic - une fois pour toutes
function getFirstElement<T>(arr: T[]): T {
return arr[0];
}
const firstString = getFirstElement(['a', 'b']); // string
const firstNumber = getFirstElement([1, 2, 3]); // numberNiveau avancé (pour surprendre) :
// Générique avec restrictions
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Alexey', age: 25 };
getProperty(user, 'name'); // ✅ OK
getProperty(user, 'salary'); // ❌ Erreur de compilation !3. « Expliquer unknown vs any vs never »
Niveau de difficulté : une question philosophique dans le monde des types
Imaginez : any est « je m'en fiche », unknown est « je ne sais pas, mais je vais vérifier », never est « cela ne peut pas être du tout ».
// any - anarchie, fais ce que tu veux
let chaos: any = 5;
chaos.doWhatever(); // Compilateur : « D'accord, c'est ton problème »
// inconnu - incertitude sûre
let mystery: unknown = 5;
// mystery.doSomething(); // ❌ Erreur !
// Vérifions d'abord
if (typeof mystery === 'number') {
mystery.toFixed(2); // ✅ Maintenant OK
}
// never - pour le code inaccessible
function throwError(message: string): never {
throw new Error(message);
// Le code n'arrivera jamais ici
}
type Shape = Circle | Square;
function getArea(shape: Shape) {
switch(shape.kind) {
case 'circle': return Math.PI * shape.radius ** 2;
case 'square': return shape.size ** 2;
default:
const _exhaustive: never = shape; // Vérification de l'exhaustivité
return _exhaustive;
}
}Règle d'or : Utilisez unknown au lieu de any lorsque vous ne connaissez pas le type. Vos collègues vous remercieront.
4. « Que sont les types d'utilitaires et lesquels utilisez-vous ? »
Niveau de difficulté : indique si vous avez travaillé sur de vrais projets
Les types d'utilitaires sont des aides TypeScript intégrées. C'est comme un couteau suisse pour les types.
interface User {
id: number;
name: string;
email: string;
password: string;
}
// Partiel - tous les champs sont facultatifs
type UserUpdate = Partial<User>;
// { id?: number; name?: string; ... }
// Pick - sélectionner les champs nécessaires
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: number; name: string }
// Omit - exclure les champs
type UserPublic = Omit<User, 'password'>;
// { id: number; name: string; email: string }
// Record - créer une structure
type UserRoles = Record<'admin' | 'user' | 'guest', string[]>;
// { admin: string[]; user: string[]; guest: string[] }
// ReturnType - type de valeur retournée
function getUser() {
return { id: 1, name: 'Alex' };
}
type User = ReturnType<typeof getUser>;Astuce pour le service de sécurité sociale : Mentionnez Readonly, Required, NonNullable – vous montrerez que vous ne connaissez pas seulement les plus populaires.
5. « Que sont les Type Guards et comment les créer ? »
Niveau de difficulté : Moyen, mais très pratique
Type Guards est un moyen de convaincre TypeScript que vous savez quel type de données vous avez devant vous.
// Type guard simple
function isString(value: unknown): value is string {
return typeof value === 'string';
}
// Plus complexe
interface Cat {
meow: () => void;
}
interface Dog {
bark: () => void;
}
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).meow !== undefined;
}
function makeSound(animal: Cat | Dog) {
if (isCat(animal)) {
animal.meow(); // TypeScript sait que c'est Cat
} else {
animal.bark(); // Et ici - Dog
}
}
// Utilisation de l'opérateur 'in'
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ('swim' in animal) {
animal.swim();
} else {
animal.fly();
}
}6. « Parlez-moi de keyof et typeof »
Niveau de difficulté : ici, les intermédiaires sont séparés des juniors
interface User {
id: number;
name: string;
email: string;
}
// keyof - on obtient l'union de toutes les clés
type UserKeys = keyof User; // 'id' | 'name' | 'email'
// typeof - obtenir le type de la valeur
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retries: 3
};
type Config = typeof config;
// { apiUrl: string; timeout: number; retries: number }
// Combo : keyof typeof
const Colors = {
red: '#ff0000',
blue: '#0000ff',
green: '#00ff00'
} as const;
type ColorKey = keyof typeof Colors; // 'red' | 'blue' | 'green'
// Application pratique
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}7. « Que sont les types mappés ? »
Niveau de difficulté : Senior territory
Les types mappés, c'est quand vous transformez un type en un autre, comme un alchimiste.
type User = {
name: string;
age: number;
email: string;
}
// Nous faisons tous les champs readonly
type ReadonlyUser = {
readonly [K in keyof User]: User[K];
};
// Nous rendons tous les champs facultatifs
type PartialUser = {
[K in keyof User]?: User[K];
};
// Nous faisons tous les champs nullable
type NullableUser = {
[K in keyof User]: User[K] | null;
};
// Créons des getters
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type UserGetters = Getters<User>;
// {
// getName: () => string;
// getAge: () => number;
// getEmail: () => string;
// }8. « Quelle est la différence entre les types enum et union ? »
Niveau de difficulté : une question simple avec un piège
// Enum - crée un véritable objet JavaScript
enum Status {
Pending = 'PENDING',
Success = 'SUCCESS',
Error = 'ERROR'
}
console.log(Status.Pending); // 'PENDING' - existe dans runtime !
// Union - uniquement au niveau des types
type StatusUnion = 'PENDING' | 'SUCCESS' | 'ERROR';
// Dans runtime, c'est juste une ligne
const status: StatusUnion = 'PENDING';
// Const enum - compilé en valeurs
const enum Direction {
Up,
Down,
Left,
Right
}
const dir = Direction.Up; // Se transforme en 0Que dire : "Je préfère les types d'union pour les cas simples, car ils n'ajoutent pas de code d'exécution. J'utilise Enum lorsque j'ai besoin de rétroaction (mappage inverse) ou lorsque des valeurs sont nécessaires au runtime. "

9. « Que sont les types conditionnels ? »
Niveau de difficulté : si vous avez compris cela, vous n'êtes plus un débutant
Conditional Types est un opérateur ternaire pour les types.
// Syntaxe de base
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// Exemple pratique
type Flatten<T> = T extends Array<infer U> ? U : T;
type StrArray = Flatten<string[]>; // string
type Num = Flatten<number>; // number
// Encore plus cool
type NonNullable<T> = T extends null | undefined ? never : T;
type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string
// Distributed Conditional Types
type ToArray<T> = T extends any ? T[] : never;
type StrOrNumArray = ToArray<string | number>;
// string[] | number[]10. « Parlez-moi de infer keyword »
Niveau de difficulté : c'est déjà de la magie
infer permet de « tirer » un type d'un autre type.
// Obtenir le type de valeur de retour de la fonction
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function getUser() {
return { id: 1, name: 'Alex' };
}
type User = ReturnType<typeof getUser>; // { id: number; name: string }
// Obtenir le type d'élément de tableau
type ArrayElement<T> = T extends (infer U)[] ? U : never;
type NumArray = number[];
type Num = ArrayElement<NumArray>; // number
// Obtenir le type de paramètres de la fonction
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
function createUser(name: string, age: number) {}
type CreateUserParams = Parameters<typeof createUser>; // [string, number]
// Promesses
type Awaited<T> = T extends Promise<infer U> ? U : T;
type AsyncResult = Awaited<Promise<string>>; // string💡 Comment se souvenir de tout cela et commencer à l'appliquer ?
Honnêtement ? Lire des articles, c'est bien, mais sans pratique, tout cela s'évaporera en une semaine. Il faut vraiment écrire du code et faire face à des problèmes.
C'est pourquoi nous avons créé Kodik – une application où la théorie se transforme immédiatement en pratique. Pas de conférences sans fin, seulement du code et des défis.
De plus, nous avons Chaîne Telegram avec une communauté de plus de 2 000 développeurs, où des messages utiles, des analyses de tâches, des mèmes (où sans eux) et des discussions sont publiés chaque jour. C'est comme Stack Overflow, mais en russe et avec une touche humaine.
Questions bonus qui peuvent également être posées :
11. « Qu'est-ce que la fusion de déclarations ? »
interface Box {
height: number;
}
interface Box {
width: number;
}
// TypeScript combinera les deux en :
// interface Box {
// height: number;
// width: number;
// }12. « Pourquoi avez-vous besoin de as const ? »
// Sans as const
const colors = ['red', 'blue']; // string[]
// Avec as const
const colorsConst = ['red', 'blue'] as const; // readonly ['red', 'blue']
// Application pratique
const routes = {
home: '/',
about: '/about',
contact: '/contact'
} as const;
type Route = typeof routes[keyof typeof routes];
// '/' | '/about' | '/contact'13. « Que sont les Template Literal Types ? »
type Direction = 'up' | 'down' | 'left' | 'right';
type Move = `move${Capitalize<Direction>}`;
// 'moveUp' | 'moveDown' | 'moveLeft' | 'moveRight'
type EventName = 'click' | 'focus' | 'blur';
type Handler = `on${Capitalize<EventName>}`;
// 'onClick' | 'onFocus' | 'onBlur'Conclusion : comment se préparer à un entretien
Une semaine avant :
Parcourir la documentation officielle de TypeScript
Résolvez les problèmes sur Type Challenges (github.com/type-challenges/type-challenges)
Entraînez-vous à expliquer les concepts à voix haute
La veille de :
Répétez les concepts de base de cet article
Préparez des exemples de vos projets
Dormez suffisamment (sérieusement, c'est plus important que de réviser)
Lors de l'entretien :
N'ayez pas peur de dire « je ne sais pas, mais je peux chercher »
Il est préférable d'expliquer le concept avec vos propres mots que de citer la documentation
Posez des questions de clarification - cela montre que vous pensez
L'essentiel : TypeScript est un outil, pas une fin en soi. Comprendre pourquoi besoin de typage, plus important que de connaître tous les types d'utilitaires par cœur.
P.S. Si après la lecture, vous avez la tête en ébullition, c'est normal. TypeScript n'est pas quelque chose que l'on apprend en une nuit. Revenez à cet article, essayez des exemples, faites des erreurs et apprenez. C'est comme ça que ça marche.
Bonne chance pour les entretiens ! Que le compilateur soit avec vous ✨
