Cheatsheets, références tsconfig, utility types et patterns — tout en un seul endroit.
Types primitifs
| Type | Syntaxe | Exemple | Notes |
string | let x: string | "hello" | Chaîne de caractères |
number | let x: number | 42, 3.14 | Entiers et flottants |
boolean | let x: boolean | true, false | |
null | let x: null | null | Valeur nulle explicite |
undefined | let x: undefined | undefined | Non initialisé |
symbol | let x: symbol | Symbol('id') | Unique et immuable |
bigint | let x: bigint | 9999n | Grands entiers |
Types spéciaux
| Type | Description | Quand utiliser |
any | Désactive toute vérification de type | À éviter — uniquement lors de migration JS→TS |
unknown | Type sûr — force la vérification avant usage | Données externes, catch blocks, JSON.parse |
never | Valeur impossible — fonction qui throw toujours | Exhaustive checks, unreachable code |
void | Retour non utilisable | Fonctions qui retournent undefined |
object | Tout type non primitif | Contraindre un générique à être un objet |
Tableaux, Tuples, Unions
// Tableaux
let nums: number[] = [1, 2, 3];
let strs: Array<string> = ["a", "b"];
// Tuples — ordre et longueur fixes
let pair: [string, number] = ["Alice", 30];
const [name, age] = pair; // destructuring typé
// Union types
let id: string | number = 42;
// Intersection types
type AdminUser = User & Admin;
// Literal types
type Direction = "left" | "right" | "up" | "down";
type HttpStatus = 200 | 201 | 400 | 401 | 404 | 500;
Référence tsconfig.json complète
| target | "ES2022" recommandé — syntaxe JS générée (ES5, ES2015, ES2020, ES2022, ESNext) |
| module | "Node16" pour Node.js, "ESNext" pour bundlers (Vite, Webpack) |
| moduleResolution | "node16" ou "bundler" — algorithme de résolution des imports |
| outDir | "./dist" — dossier de sortie des .js compilés |
| rootDir | "./src" — dossier source des .ts |
| declaration | true — génère les .d.ts (obligatoire pour les packages npm) |
| sourceMap | true — génère les source maps pour le debugging |
| strict ✓ | Active toutes les options strict* en une fois recommandé |
| strictNullChecks | null/undefined ne sont plus assignables aux autres types |
| noImplicitAny | Interdit les paramètres/variables sans type explicite |
| strictFunctionTypes | Vérifie la contravariance des paramètres de fonctions |
| strictPropertyInitialization | Les propriétés de classe doivent être initialisées |
| noUncheckedIndexedAccess | L'accès par index retourne T | undefined (sécurité supplémentaire) |
| exactOptionalPropertyTypes | Une prop?: string ne peut pas avoir la valeur undefined (uniquement absente) |
| esModuleInterop | true — imports compatibles CommonJS : import lodash from 'lodash' |
| allowSyntheticDefaultImports | true — permet les imports default pour les modules sans export default |
| baseUrl | "." ou "./src" — base pour la résolution des imports relatifs |
| paths | Alias : { "@/*": ["./src/*"] } — importer depuis @/components/Button |
| resolveJsonModule | true — permet d'importer des fichiers .json |
// tsconfig.json — configuration recommandée Node.js
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"declaration": true,
"sourceMap": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
Type Guards
// typeof guard
function process(val: string | number) {
if (typeof val === "string") {
// val: string ici
return val.toUpperCase();
}
// val: number ici
return val * 2;
}
// instanceof guard
function handleError(err: unknown) {
if (err instanceof Error) {
console.log(err.message); // err: Error
}
}
// User-defined type guard
function isUser(val: unknown): val is User {
return typeof val === "object" && val !== null
&& "id" in val && "name" in val;
}
// Discriminated union guard
type Shape = { kind: "circle"; radius: number } | { kind: "square"; side: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
default: const _: never = s; // exhaustive check
}
}
Génériques avancés
// Générique avec contrainte keyof
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Conditional type récursif
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object
? DeepReadonly<T[K]>
: T[K];
};
// Template literal types
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};
// infer dans conditional type
type Unwrap<T> = T extends Promise<infer R> ? R : T;
// Unwrap<Promise<string>> → string
Declaration Merging — Augmenter Express
// src/types/express.d.ts
import { User } from "../models/user";
declare namespace Express {
interface Request {
user?: User;
requestId?: string;
}
}
// Middleware — req.user est maintenant typé
const auth = (req: Request, res: Response, next: NextFunction) => {
req.user = verifyToken(req.headers.authorization);
next();
};
Référence rapide — React + TypeScript
| Cas | Type à utiliser |
| Children d'un composant | React.ReactNode |
| Référence DOM input | RefObject<HTMLInputElement> |
| Événement onChange input | React.ChangeEvent<HTMLInputElement> |
| Événement onClick bouton | React.MouseEvent<HTMLButtonElement> |
| Événement onSubmit form | React.FormEvent<HTMLFormElement> |
| État useState nullable | useState<User | null>(null) |
| Context API | createContext<T | null>(null) |
| Composant fonctionnel | React.FC<Props> ou (props: Props) => |
| Custom hook générique | function useFetch<T>(url: string): FetchState<T> |
| useReducer | useReducer<Reducer<State, Action>> |
// Composant typé complet
interface CardProps {
title: string;
children: React.ReactNode;
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
variant?: "default" | "primary";
}
const Card: React.FC<CardProps> = ({ title, children, onClick, variant = "default" }) => (
<div className={`card card--${variant}`} onClick={onClick}>
<h2>{title}</h2>
{children}
</div>
);
Express + TypeScript — référence
// Types Express principaux
import { Request, Response, NextFunction, Router } from "express";
// Request générique
type TypedRequest<P, B> = Request<P, any, B>;
const createUser = async (
req: TypedRequest<{}, CreateUserDto>,
res: Response<ApiResponse<User>>,
next: NextFunction
) => {
const body = CreateUserSchema.parse(req.body);
const user = await prisma.user.create({ data: body });
res.status(201).json({ data: user, status: 201 });
};
Variables d'environnement typées avec Zod
// src/config/env.ts
import { z } from "zod";
const EnvSchema = z.object({
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
NODE_ENV: z.enum(["development", "production", "test"]),
});
export const env = EnvSchema.parse(process.env);
// env.PORT: number, env.DATABASE_URL: string, etc.
Prisma — utilisation typée
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// Type inféré automatiquement
const user = await prisma.user.findUnique({ where: { id: 1 } });
// user: User | null (type généré par Prisma)
// ReturnType pour wrapper les appels
type UserWithPosts = Awaited<ReturnType<typeof prisma.user.findUnique>>;