← TypeScript Cheatsheet TS 5.x
1

Types primitifs & Annotations

TS
// Primitifs
let nom: string = "Alice";
let age: number = 30;            // int et float = number
let big: bigint = 100n;
let ok: boolean = true;
let sym: symbol = Symbol("id");
let nul: null = null;
let und: undefined = undefined;

// SpΓ©ciaux
let anything: any = "no check";    // dΓ©sactive le type-checking β€” Γ©viter
let unknown_val: unknown = 42;    // type-safe any β€” prΓ©fΓ©rer
function fail(): never { throw new Error(); }  // jamais de retour
function log(): void { console.log("hi"); }  // pas de valeur retour

// Arrays
let nums: number[] = [1, 2, 3];
let strs: Array<string> = ["a", "b"];      // forme gΓ©nΓ©rique
let matrix: number[][] = [[1,2],[3,4]];

// Tuples
let pair: [string, number] = ["Alice", 30];
let named: [name: string, age: number] = ["Bob", 25];  // labeled
let rest: [string, ...number[]] = ["sum", 1, 2, 3];   // variadic
const tuple = ["a", 1] as const;   // readonly ["a", 1]

// Type inference — TS infère quand c'est évident
const x = 42;       // type: 42 (literal type)
let y = 42;         // type: number (widening)
2

Interfaces

TS
interface User {
  readonly id: number;         // lecture seule
  name: string;
  email?: string;              // optionnel
  age: number;
}

// Index signatures
interface Dict {
  [key: string]: number;       // clΓ©s string, valeurs number
}

// Callable / Constructable
interface Fn {
  (x: number): string;          // call signature
}
interface Ctor {
  new (name: string): User;     // construct signature
}

// HΓ©ritage (extends β€” multiple ok)
interface Admin extends User {
  role: "admin" | "superadmin";
}

interface Timestamped {
  createdAt: Date;
  updatedAt: Date;
}

interface AdminTimestamped extends Admin, Timestamped {}

// Declaration merging (interface seulement, pas type)
interface User { phone?: string; }  // s'ajoute Γ  User existant

// Generic interface
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}
3

Types & Alias

TS
// Type alias
type ID = string | number;
type Point = { x: number; y: number };
type Callback = (data: string) => void;

// Interface vs Type β€” quand utiliser quoi ?
// Interface : objets, classes (extends, implements, merging)
// Type      : unions, intersections, tuples, mapped types, primitifs

// Object type
type Config = {
  readonly host: string;
  port?: number;
  [key: string]: unknown;
};

// Record shorthand
type Scores = Record<string, number>;  // { [key: string]: number }
4

Union, Intersection, Literal Types

TS
// ── Union : A OU B ──
type Result = string | number | null;
type Status = "idle" | "loading" | "success" | "error";

// Discriminated union (pattern très courant)
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "rect"; width: number; height: number }
  | { kind: "triangle"; base: number; height: number };

function area(s: Shape): number {
  switch (s.kind) {
    case "circle":   return Math.PI * s.radius ** 2;
    case "rect":     return s.width * s.height;
    case "triangle": return s.base * s.height / 2;
    default:        const _exhaustive: never = s; return _exhaustive;
  }
}

// ── Intersection : A ET B ──
type WithTimestamps = { createdAt: Date; updatedAt: Date };
type UserWithTimestamps = User & WithTimestamps;

// ── Literal types ──
type Direction = "up" | "down" | "left" | "right";
type Bit = 0 | 1;
type Bool = true | false;

// as const β€” assertion de constante
const COLORS = ["red", "green", "blue"] as const;
type Color = (typeof COLORS)[number];  // "red" | "green" | "blue"

// satisfies (TS 5.0) β€” valide le type sans le widener
const config = {
  port: 3000,
  host: "localhost",
} satisfies Record<string, string | number>;
// config.port est infΓ©rΓ© comme 3000 (literal), pas string | number
5

Enums

TS
// Numeric enum (auto-incrΓ©mentΓ©)
enum Direction { Up, Down, Left, Right }  // 0, 1, 2, 3
enum Status { Active = 1, Inactive = 2 }

// String enum (prΓ©fΓ©rer)
enum Role {
  Admin = "ADMIN",
  User  = "USER",
  Guest = "GUEST",
}
const r: Role = Role.Admin;

// const enum β€” inlinΓ© Γ  la compilation (pas d'objet runtime)
const enum Color { Red, Green, Blue }

// Alternative moderne : union de littΓ©raux (souvent prΓ©fΓ©rΓ©)
type Role = "admin" | "user" | "guest";

// Reverse mapping (numeric enum seulement)
Direction[0]  // "Up"
Direction.Up  // 0
6

Fonctions typΓ©es

TS
// Paramètres et retour
function add(a: number, b: number): number { return a + b; }

// Arrow avec type
const add: (a: number, b: number) => number = (a, b) => a + b;

// Optionnels et dΓ©fauts
function greet(name: string, prefix?: string): string { ... }
function greet(name: string, prefix = "Hello"): string { ... }

// Rest params
function sum(...nums: number[]): number { ... }

// Function type alias
type Handler = (event: Event) => void;
type AsyncFn<T> = () => Promise<T>;

// Overloads
function parse(input: string): number;
function parse(input: number): string;
function parse(input: string | number): string | number {
  return typeof input === "string" ? Number(input) : String(input);
}

// this parameter (premier param, effacΓ© Γ  la compilation)
function onClick(this: HTMLButtonElement, e: Event) {
  this.disabled = true;
}

// Assertion functions
function assertDefined<T>(val: T): asserts val is NonNullable<T> {
  if (val == null) throw new Error("Expected defined");
}

// Generic function
function first<T>(arr: T[]): T | undefined { return arr[0]; }
7

Classes

TS
class User {
  // Modificateurs d'accès
  public name: string;          // dΓ©faut, accessible partout
  private _email: string;       // accessible seulement dans cette classe
  protected role: string;       // accessible dans cette classe + sous-classes
  readonly id: number;          // lecture seule après construction

  // Parameter properties (raccourci)
  constructor(
    public name: string,
    private _email: string,
    readonly id: number,
  ) {}

  // Getter / Setter
  get email(): string { return this._email; }
  set email(val: string) {
    if (!val.includes("@")) throw new Error("Invalid");
    this._email = val;
  }

  // MΓ©thode statique
  static create(name: string): User { ... }
}

// Implements β€” une classe satisfait une interface
interface Serializable { toJSON(): string; }
class Model implements Serializable {
  toJSON() { return JSON.stringify(this); }
}

// Abstract class
abstract class Shape {
  abstract area(): number;     // doit Γͺtre implΓ©mentΓ©
  describe() { return `Area: ${this.area()}`; }
}

class Circle extends Shape {
  constructor(private r: number) { super(); }
  area() { return Math.PI * this.r ** 2; }
}
8

Generics

TS
// ── Fonction gΓ©nΓ©rique ──
function identity<T>(val: T): T { return val; }
identity<string>("hello");  // explicite
identity(42);               // infΓ©rΓ© β†’ T = number

// ── Contraintes (extends) ──
function getLength<T extends { length: number }>(x: T): number {
  return x.length;
}

// ── Plusieurs paramΓ¨tres ──
function merge<A, B>(a: A, b: B): A & B {
  return { ...a, ...b };
}

// ── Generic avec keyof ──
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// ── Interface gΓ©nΓ©rique ──
interface Repository<T> {
  findById(id: string): Promise<T | null>;
  save(entity: T): Promise<T>;
  delete(id: string): Promise<void>;
}

// ── Classe gΓ©nΓ©rique ──
class Stack<T> {
  private items: T[] = [];
  push(item: T) { this.items.push(item); }
  pop(): T | undefined { return this.items.pop(); }
}

// ── Default type parameter ──
type ApiRes<T = unknown> = { data: T; status: number };
9

Type Guards & Narrowing

TS
// typeof
if (typeof x === "string") { x.toUpperCase(); }

// instanceof
if (err instanceof TypeError) { err.message; }

// in operator
if ("email" in user) { user.email; }

// Discriminated union (switch sur le discriminant)
switch (shape.kind) { ... }

// Truthiness
if (user.name) { /* string (pas undefined, pas "") */ }

// Custom type guard (type predicate)
function isString(val: unknown): val is string {
  return typeof val === "string";
}

// Assertion function
function assertNonNull<T>(val: T): asserts val is NonNullable<T> {
  if (val == null) throw new Error("Null!");
}

// Non-null assertion (!) β€” Γ  Γ©viter si possible
const el = document.getElementById("app")!;  // ! = "trust me, not null"

// as (type assertion) β€” Γ©viter aussi
const input = el as HTMLInputElement;

// Exhaustive check
function assertNever(x: never): never {
  throw new Error(`Unexpected: ${x}`);
}
10

Mapped Types

TS
// Syntaxe : { [K in Keys]: Type }

// Tout optionnel
type MyPartial<T> = { [K in keyof T]?: T[K] };

// Tout readonly
type MyReadonly<T> = { readonly [K in keyof T]: T[K] };

// Modifier les modificateurs (+ / -)
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
type Required<T> = { [K in keyof T]-?: T[K] };

// Renommer les clΓ©s (as)
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};
// { getName: () => string; getAge: () => number; }

// Filtrer les clΓ©s
type OnlyStrings<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K]
};

// keyof
type UserKeys = keyof User;  // "name" | "email" | "age"

// Indexed access
type NameType = User["name"];  // string
type AllValues = User[keyof User];  // string | number
11

Conditional Types

TS
// Syntaxe : T extends U ? X : Y

type IsString<T> = T extends string ? true : false;
IsString<string>  // true
IsString<number>  // false

// Distribution sur les unions
type ToArray<T> = T extends any ? T[] : never;
ToArray<string | number>  // string[] | number[]

// EmpΓͺcher la distribution
type ToArray<T> = [T] extends [any] ? T[] : never;
ToArray<string | number>  // (string | number)[]

// infer β€” extraire un type dans un conditionnel
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type Flatten<T> = T extends (infer U)[] ? U : T;
Flatten<string[]>   // string
Flatten<number>     // number

// Unwrap Promise
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;
12

Template Literal Types

TS
type EventName = `on${Capitalize<"click" | "focus" | "blur">}`;
// "onClick" | "onFocus" | "onBlur"

type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
type Endpoint = `/${string}`;
type Route = `${HTTPMethod} ${Endpoint}`;

// Intrinsic string types
Uppercase<"hello">      // "HELLO"
Lowercase<"HELLO">      // "hello"
Capitalize<"hello">     // "Hello"
Uncapitalize<"Hello">   // "hello"

// Pattern matching avec infer
type ExtractParams<T> = T extends `${string}:${infer Param}/${infer Rest}`
  ? Param | ExtractParams<Rest>
  : T extends `${string}:${infer Param}`
  ? Param
  : never;

ExtractParams<"/users/:id/posts/:postId">  // "id" | "postId"
13

Utility Types (built-in)

TypeDescriptionExemple
Partial<T>Toutes les props optionnellesPartial<User>
Required<T>Toutes les props obligatoiresRequired<Config>
Readonly<T>Toutes les props en lecture seuleReadonly<State>
Record<K, V>Objet avec clΓ©s K, valeurs VRecord<string, number>
Pick<T, K>Garde seulement les clΓ©s KPick<User, "name" | "email">
Omit<T, K>Exclut les clΓ©s KOmit<User, "password">
Exclude<T, U>Retire U de l'union TExclude<"a"|"b"|"c", "a"> β†’ "b"|"c"
Extract<T, U>Garde seulement U de TExtract<string|number, string> β†’ string
NonNullable<T>Retire null et undefinedNonNullable<string|null> β†’ string
ReturnType<T>Type de retour d'une fonctionReturnType<typeof fn>
Parameters<T>Tuple des paramètresParameters<typeof fn>
ConstructorParameters<T>Params du constructeurConstructorParameters<typeof Date>
InstanceType<T>Type d'instance d'une classeInstanceType<typeof User>
Awaited<T>Unwrap Promise rΓ©cursivementAwaited<Promise<string>> β†’ string
NoInfer<T>EmpΓͺche l'infΓ©rence (TS 5.4)NoInfer<T>
14

Infer & Advanced Patterns

TS
// Deep Partial
type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]
};

// Deep Readonly
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K]
};

// Branded types (type nominal)
type Brand<T, B> = T & { __brand: B };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
// UserId et OrderId ne sont pas interchangeables

// Builder pattern typΓ©
type Builder<T, Built = {}> = {
  set<K extends keyof T>(key: K, val: T[K]): Builder<T, Built & Record<K, T[K]>>;
  build(): Built;
};

// Extract function argument types at position
type FirstArg<T> = T extends (first: infer A, ...rest: any[]) => any ? A : never;

// Variadic tuples
type Concat<A extends any[], B extends any[]> = [...A, ...B];
Concat<[1, 2], [3, 4]>  // [1, 2, 3, 4]
15

Modules & Namespaces

TS
// ── ESM (standard, prΓ©fΓ©rer) ──
export interface User { name: string; }
export type ID = string;
export const PI = 3.14;

// Import de type uniquement (tree-shakeable)
import type { User, ID } from "./models";
import { type User, createUser } from "./models"; // inline type import

// ── Namespaces (legacy, Γ©viter dans les nouveaux projets) ──
namespace Validation {
  export interface Validator { validate(s: string): boolean; }
}

// ── Module augmentation ──
declare module "express" {
  interface Request {
    user?: User;
  }
}

// ── Global augmentation ──
declare global {
  interface Window { analytics: Analytics; }
}
16

Decorators (TS 5.0+)

TS
// ── Stage 3 Decorators (TS 5.0+, standard TC39) ──
function log(target: any, context: ClassMethodDecoratorContext) {
  const name = String(context.name);
  return function(this: any, ...args: any[]) {
    console.log(`Calling ${name}`);
    return target.call(this, ...args);
  };
}

class Service {
  @log
  getData() { return "data"; }
}

// Class decorator
function sealed(target: Function, _ctx: ClassDecoratorContext) {
  Object.seal(target);
  Object.seal(target.prototype);
}

@sealed
class MyClass { ... }

// Cible des decorators : classes, methods, accessors, fields, auto-accessors
17

Declaration Files (.d.ts)

TS
// ── Fichier .d.ts β€” types pour des libs JS sans types ──

// DΓ©clarer un module
declare module "my-lib" {
  export function doStuff(x: string): number;
  export interface Config { debug: boolean; }
  export default class Client {
    constructor(config: Config);
  }
}

// Wildcard module (CSS, images, etc.)
declare module "*.css" {
  const content: Record<string, string>;
  export default content;
}
declare module "*.png" {
  const src: string;
  export default src;
}

// Variables globales
declare const __VERSION__: string;
declare function gtag(...args: any[]): void;

// @types/xxx β€” types DefinitelyTyped (npm)
// npm install @types/node @types/react
18

tsconfig.json

JSON
{
  "compilerOptions": {
    // ── Target & Module ──
    "target": "ES2022",           // version JS de sortie
    "module": "NodeNext",         // système de modules
    "moduleResolution": "NodeNext",
    "lib": ["ES2023", "DOM", "DOM.Iterable"],

    // ── Strict (tout activer)
    "strict": true,               // active toutes les vΓ©rifs strictes
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "exactOptionalPropertyTypes": true,

    // ── Output ──
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,          // génère .d.ts
    "sourceMap": true,
    "declarationMap": true,

    // ── Interop ──
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "isolatedModules": true,      // requis pour Vite/esbuild
    "verbatimModuleSyntax": true,  // TS 5.0+

    // ── Paths ──
    "baseUrl": ".",
    "paths": { "@/*": ["src/*"] },

    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
19

TS 5.x NouveautΓ©s

TS 5.0 – 5.5
// ── TS 5.0 ──
// β€’ Decorators (TC39 stage 3)
// β€’ const type parameters
function asConst<const T>(val: T): T { return val; }
asConst([1, 2, 3]);  // readonly [1, 2, 3] au lieu de number[]

// β€’ satisfies operator
const cfg = { port: 3000 } satisfies Record<string, number>;

// ── TS 5.1 ──
// β€’ Easier implicit returns for undefined
// β€’ Unrelated types for getters/setters

// ── TS 5.2 ──
// β€’ using (Explicit Resource Management)
{
  using file = openFile("data.txt");
  // file[Symbol.dispose]() appelΓ© automatiquement Γ  la sortie du bloc
}
// β€’ Decorator metadata

// ── TS 5.3 ──
// β€’ Import attributes
import data from "./data.json" with { type: "json" };

// ── TS 5.4 ──
// β€’ NoInfer<T> β€” empΓͺche l'infΓ©rence sur un paramΓ¨tre
function createStore<T>(initial: T, allowed: NoInfer<T>[]) { ... }

// β€’ Narrowing amΓ©liorΓ© dans les closures

// ── TS 5.5 ──
// β€’ Inferred type predicates
// β€’ Regular expression syntax checking
// β€’ Isolated declarations
20

Bonnes pratiques

Conseils
// βœ… Activer "strict": true dans tsconfig
// βœ… PrΓ©fΓ©rer unknown Γ  any
// βœ… Utiliser les discriminated unions pour le state
// βœ… PrΓ©fΓ©rer interface pour les objets, type pour les unions/intersections
// βœ… Utiliser as const pour les constantes littΓ©rales
// βœ… satisfies pour valider sans widener
// βœ… import type pour les imports de type uniquement
// βœ… Type guards custom pour le narrowing complexe
// βœ… Exhaustive checks avec never dans les switch
// βœ… Readonly<T> pour les donnΓ©es immutables
// βœ… Branded types pour les IDs (UserId vs OrderId)
// βœ… Zod / Valibot pour la validation runtime + infΓ©rence de type

// ❌ any partout β€” dΓ©sactive tout le bΓ©nΓ©fice de TS
// ❌ as Type (assertions) quand un type guard est possible
// ❌ Non-null assertion (!) sans Γͺtre sΓ»r
// ❌ @ts-ignore sans commentaire explicatif
// ❌ Enums numΓ©riques β€” prΓ©fΓ©rer string enums ou unions
// ❌ Namespaces dans les projets modernes β€” utiliser ESM
// ❌ Oublier noUncheckedIndexedAccess (arrays, records)
// ❌ Types trop complexes qui nuisent à la lisibilité

TypeScript Cheatsheet Complet β€” TS 5.x β€” 2026