2017-07-04 3 views
0

J'ai une fonction (comparaison) avec un type de retour union. Il peut renvoyer -1, 1 ou 0. Cependant, j'ai besoin d'un cas spécial ("résultat") pour quand au moins un des éléments comparés n'est pas défini. Le compilateur me permet d'ajouter null comme valeur de retour potentielle, mais pas NaN (ce qui, dans certains scénarios, aurait du sens, par exemple en comparant des nombres ou des dates).Type d'union entier (littéral), avec NaN comme valeur de retour valide

Cette compile

function myFunc(item1: MyType, item2: MyType): -1 | 0 | 1 | null { 
    ... 
} 

mais pour celui-ci, le compilateur dit qu'il "ne peut pas trouver le nom NaN":

function myFunc(item1: MyType, item2: MyType): -1 | 0 | 1 | NaN { 
    ... 
} 

Pourquoi NaN pas autorisé? Est-il possible d'utiliser NaN?

+0

NaN n'est pas un float int, c'est probablement pourquoi TS ne l'aime pas. – mfeineis

+0

@mfeine est sûr, mais cette 'fonction bla(): 1 | "3" | null {...} 'compile également. –

+0

JavaScript ne diffère pas entre int et float. Les deux sont du même type 'Number'. Je pense que NaN est aussi 'Number'. – Misaz

Répondre

2

NaN lui-même n'est pas un type, à la place il s'agit d'une valeur const de type Number. Il n'y a donc aucun moyen de définir quoi que ce soit comme étant de type NaN.

Cela a du sens, car les types littéraux pour les nombres sont tous des valeurs uniques, par ex. -1, ou une union des valeurs littérales 1 | 0 | -1 mais NaN n'est pas une seule valeur car aucun NaN ne compare jamais égal à un autre c'est effectivement un ensemble infini de valeurs.

Je suggère que l'utilisation de NaN pour indiquer un résultat particulier de votre fonction est une mauvaise idée car la seule façon que vous pouvez tester pour obtenir ce résultat est d'appeler une autre fonction. Mieux vaut ajouter null ou undefined au type de retour (ou si vous n'aimez pas cela à propos d'une chaîne littérale).

Gardez à l'esprit que:

let foo = NaN; 
switch(foo) { 
    case 1: console.log('got 1'); break 
    case NaN: console.log('got NaN'); break; 
    default: console.log('other'); 
} 

Affichera 'autre'.

Alors vous pouvez simplement faire ceci:

function myFunc(item1: MyType, item2: MyType): -1 | 0 | 1 | 'not comparable' { 
    ... 
} 

et vous pouvez simplement comparer le résultat contre « pas comparable ».

+0

Mis à part la portée de la fonction (qui était plus d'un exemple, plutôt que le problème réel - j'ai fini par utiliser «null»).Le fait est que je peux considérer toutes les valeurs ('-1',' 0', '1' et' NaN') comme des constantes. Ceci, à son tour, signifie que j'ai une fonction qui devrait être capable de renvoyer une valeur (constante), à ​​partir d'un ensemble spécifique de valeurs. Le compilateur TS n'est pas d'accord ... –

+0

oui, mais mon point est que NaN n'est pas une valeur unique, mais plutôt une classe de valeurs. – Duncan

1

Contrairement 1, NaN ne peut pas être utilisé comme un literal type (à savoir un type qui ne contient que valeur littérale).

const n1 = 1, n2 = NaN; 
typeof n1; // 1 
typeof n2; // number 

On pourrait aussi utiliser number comme type de retour, mais cela permettrait plus de valeurs de retour comme -2. Si vous voulez limiter les options, null me semble bon.