Menu

Tableaux en TypeScript : types, tableaux d'objets, map et filter

Typer les tableaux en TypeScript : T[] ou Array<T>, tableaux d'objets, tableaux contenant plusieurs types, tableaux readonly, et ce que renvoient map, filter, reduce et find. Plus le piège de includes avec les tableaux de littéraux.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Un type tableau TypeScript s'écrit avec le type des éléments suivi de [] : string[] est un tableau de chaînes, number[] un tableau de nombres. L'écriture générique Array<string> désigne le même type. Une fois le tableau typé, chaque élément que vous ajoutez et chaque élément que vous lisez a ce type.

La ligne @ts-expect-error est une erreur de compilation (TS2345). Elle est marquée ici comme attendue pour que le bloc s'exécute quand même, et comme les types sont effacés, le 42 est bel et bien ajouté à l'exécution : la sortie le montre.

string[] ou Array<string>

ÉcritÉquivaut àRemarques
string[]Array<string>L'écriture courante.
(string | number)[]Array<string | number>Les parenthèses sont obligatoires : string | number[] signifie « une chaîne, ou un tableau de nombres ».
readonly string[]ReadonlyArray<string>Pas de push, pop, sort ni d'assignation par indice.
User[]Array<User>Les tableaux d'objets utilisent le type de l'objet.
string[][]Array<Array<string>>Un tableau à deux dimensions (grille).

Choisissez un style par base de code. La règle array-type de typescript-eslint utilise T[] par défaut.

Tableaux d'objets

Décrivez l'élément avec un alias de type ou une interface, puis utilisez Type[]. Tout ce qui est lu dans le tableau est vérifié par rapport à cette forme.

Un littéral objet ajouté à users doit correspondre exactement à User : un admin manquant ou une propriété mal orthographiée est une erreur de compilation.

map, filter, reduce et find typés

Les méthodes de tableau sont génériques, leurs résultats portent donc des types. Ce que fait chaque méthode à l'exécution est expliqué sur la page JavaScript des méthodes de tableau ; les types sont l'apport de TypeScript :

MéthodeType du résultat sur T[]
map(fn)U[], où U est ce que renvoie fn
filter(fn)T[] (ou un type plus étroit, voir plus bas)
find(fn)T | undefined
findIndex(fn), indexOf(x)number (-1 si absent)
some(fn), every(fn), includes(x)boolean
reduce(fn, init)le type de init (ou l'argument de type, reduce<R>(...))
at(i)T | undefined
join(sep)string

Le dernier exemple fonctionne parce que TypeScript (depuis la 5.5) infère que (n) => n !== undefined est un prédicat de type, si bien que filter renvoie number[] au lieu de (number | undefined)[]. Pour les vérifications qu'il ne sait pas inférer, écrivez le prédicat vous-même : filter((x): x is User => x !== null).

Tableaux contenant plus d'un type

Une union comme type d'élément autorise le mélange. Une union de types tableau, non :

Quand les positions ont des types fixes, comme une paire [name, age], utilisez plutôt un tuple : [string, number] sait que l'indice 0 est une chaîne et l'indice 1 un nombre, ce que (string | number)[] ignore.

Tableaux readonly

readonly T[] retire toutes les méthodes qui modifient le tableau. Utilisez-le pour les paramètres qu'une fonction ne doit pas changer, et pour les constantes.

index.ts(3,12): error TS2339: Property 'push' does not exist on type 'readonly number[]'.

Supprimez la ligne push et le bloc affiche 4. Un number[] modifiable peut toujours être passé là où readonly number[] est attendu, les paramètres readonly ne coûtent donc rien aux appelants. La vérification n'a lieu qu'à la compilation : à l'exécution, c'est un tableau ordinaire. Pour trier un tableau readonly, triez une copie : [...values].sort().

Le piège de includes avec les tableaux de littéraux

as const transforme un tableau en tuple readonly de types littéraux. C'est pratique pour une liste de valeurs autorisées, mais son includes n'accepte alors que ces littéraux :

Placer la vérification dans un type guard (value is Color) fait que l'élargissement n'a lieu qu'une fois, et les appelants récupèrent une valeur affinée.

Indices et tableaux vides

Lire arr[i] donne le type T, même quand i est hors limites et que la valeur à l'exécution est undefined. at(i) est typé T | undefined, et l'option de compilation noUncheckedIndexedAccess fait aussi renvoyer T | undefined à l'accès simple par indice.

queue[0].toUpperCase() compilerait puis lèverait une TypeError à l'exécution. Préférez at(), une vérification de longueur, ou noUncheckedIndexedAccess quand un indice peut manquer.

Questions fréquentes

Comment déclarer un type tableau en TypeScript ?

Écrivez le type des éléments suivi de [] : let names: string[] = ["a", "b"]. La forme générique Array<string> signifie exactement la même chose. Pour un tableau d'objets, utilisez un type objet ou une interface comme type d'élément : User[].

Quelle est la différence entre string[] et Array<string> ?

Aucune : ce sont deux écritures du même type. string[] est la plus courante. La forme générique se lit mieux pour des types d'éléments complexes, et pour les tableaux readonly, readonly string[] et ReadonlyArray<string> sont de même équivalents.

Pourquoi find renvoie-t-il undefined en TypeScript ?

array.find() renvoie T | undefined parce que rien ne correspond peut-être. Avec strict, vous devez traiter le cas undefined, avec un if, le chaînage optionnel (found?.name) ou une valeur par défaut (found ?? fallback), avant d'utiliser le résultat.

Comment typer un tableau contenant plusieurs types en TypeScript ?

Utilisez une union comme type d'élément, entre parenthèses : (string | number)[] est un tableau dont chaque élément est une chaîne ou un nombre. C'est différent de string[] | number[], qui est soit un tableau de chaînes uniquement, soit un tableau de nombres uniquement. Pour un ordre de types fixe, comme [string, number], utilisez un tuple.

Pourquoi includes provoque-t-il une erreur sur un tableau as const ?

Un tableau readonly de littéraux, comme ["red", "green"] as const, possède includes(searchElement: "red" | "green"), donc passer un simple string provoque l'erreur TS2345. Élargissez le tableau pour la vérification, (COLORS as readonly string[]).includes(input), idéalement dans un type guard qui affine input en l'union de littéraux.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER