3 votes

Pourquoi ces types structurellement similaires sont-ils incompatibles ?

Si je déclare les types suivants :

export type Type1 = { id: string } | { id: number };
export type Type2 = { id: string } | { id: number };

Pourquoi est-ce que j'obtiens une erreur lorsque je l'utilise de la manière suivante :

function displayItem(item: Type1) {
  loadItem({ id: item.id });          // error is indicated here
}

function loadItem(item: Type2) {}

enter image description here

D'après ce que j'ai compris https://www.typescriptlang.org/docs/handbook/type-compatibility.html est qu'ils devraient être équivalents car ils sont structurellement les mêmes.

Reproduction plus simple à la lumière des réponses (le deuxième type n'est pas nécessaire) :

export type Type1 = { id: string } | { id: number };

function displayItem(item: Type1) {
   loadItem({ id: item.id });          // error is indicated here
}

function loadItem(item: Type1) {}

3voto

Bunyamin Coskuner Points 3912

Ce n'est pas que Type1 n'est pas équivalent à Type2

Par exemple, l'exemple suivant ne donnera pas d'erreur

function displayItem(item: Type1) {
  loadItem(item);
}

function loadItem(item: Type2) {}

Le problème se pose lorsque vous tapez item.id ce qui pourrait être deux choses. Depuis Type1 est défini comme suit export type Type1 = { id: string } | { id: number }; le type de cette variable pourrait être string o number . Ainsi, le script crée un autre type pour {id: item.id} qui est {id: number | string} comme vous pouvez le constater, il n'est pas compatible avec Type2 .

Vous devez écrire explicitement quel type vous souhaitez utiliser.

L'erreur suivante ne se produira pas

function displayItem(item: Type1) {
  loadItem({ id: item.id as number});         
}

Maintenant, je marque item.id como number donc type de { id: item.id as number} es {id: number} qui est compatible avec Type2

Il suffit de modifier vos types de caractères comme suit

export type Type1 = { id: string | number};
export type Type2 = { id: string | number};

3voto

VRoxa Points 877

En profondeur, vous essayez d'assigner une valeur de type number | string soit number ou un string .

Puisque vous accédez à item.id , id peut être string o number par la définition de votre type. Votre Type2 attend un objet {id: string} o {id: number} qui est différent de {id: string | number} .

Donc, deux scénarios différents pourraient résoudre cette mésaventure.

  1. Déclarez votre Type2 pour s'attendre à une clé appelée id qui est number | string
  2. Passez l'ensemble item à votre deuxième fonction. C'est ce que l'on appelle compatibilité des types

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X