網站搜尋

typescript - 整數(字面值)聯合類型,NaN 作為有效返回值


我有一個帶有聯合返回類型的(比較)函數。它可以返回 -1、1 或 0。然而,我需要一個特殊情況("result"),當至少有一個被比較的項目未定義時使用。編譯器允許我將 null 作為潛在返回值,但不允許 NaN(在某些情況下這是有意義的,例如比較數字或日期)。

這可以編譯

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

但對於這個,編譯器說它「找不到名稱 NaN」:

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

為什麼不允許 NaN?有辦法使用 NaN 嗎?

答案#1

NaN 本身不是一種類型,它是一個 Number 類型的 const 值。因此,無法將任何東西定義為 NaN 類型。

這很有道理,因為數字的字面類型都是單一值,例如 -1,或者是字面值的聯合 1 | 0 | -1,但 NaN 並不是單一值,因為沒有任何 NaN 會與其他值相等,它實際上是一個無限的值集合。

我建議使用 NaN 來表示你的函數的特定結果是一個壞主意,因為你檢測是否得到那個結果的唯一方法是調用另一個函數。最好是在返回類型中添加 null 或 undefined(或者如果你不喜歡這樣,怎麼樣用一個字面字串呢)。

請記住:

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

將輸出 'other'。

所以你可以這樣做:

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

然後你就可以將結果與「不可比較」進行比較。

答案#2

與 1 不同,NaN 不能被用作 字面量類型(即只包含該字面值的類型)。

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

我們也可以使用 number 作為返回類型,但這樣會允許更多的返回值,例如 -2。如果你想限制選項,null 對我來說看起來不錯。