![](/img/trans.png)
[英]How to define param names and types for a function which accepts 1 parameter or 2 parameters, in typescript?
[英]How to define a function which only accepts parameters which may be a type in typescript?
我想定義一個函數,如:
function isNumber(param: ???): param is number {
}
如果參數可能是一個數字,例如number | string
number | string
, number | boolean
number | boolean
,它可以傳遞給函數。 如果不是,例如它的類型是string
或boolean
,就會出現編譯錯誤。
是否可以定義這樣的類型?
從概念上講,您希望isNumber()
在param
的類型T
中通用,但您希望T
的下限為number
。 這與被認為是上限的正常extends
約束相反。 不幸的是,TypeScript 不直接支持下界泛型。 這是在microsoft/TypeScript#14520中請求的,如果它曾經實現過,它可能會使用super
而不是extends
並且看起來像
// NOT VALID TS (as of 4.7), DON'T DO THIS
function isNumber<T super number>(param: T): param is number {
return typeof param === "number"
}
但是,正如我所說,我們不能這樣做。
相反,我們可以通過在條件類型上使用常規上限來模擬下界泛型。 像T extends (U extends T ? unknown : never)
這樣的東西會表現得有點像T super U
。 如果T
是U
的超類型,則(U extends T ? unknown : never)
計算結果為unknown
,因此滿足約束 ( T extends unknown
)。 否則, (U extends T ? unknown : never)
的計算結果為never
,因此可能不滿足約束 ( T extends never
)(除非T
never
自身,無法通過這種方式進行防范)。
在您的情況下,如果T
是number
的超類型或子類型,我們實際上很好,所以我們可以寫T extends (number extends T ? unknown : number)
並且如果T
恰好是像14
這樣的數字文字類型,那么一切仍然作品。
一個問題是編譯器不明白param
可能是number
的超類型,所以你不能返回類型謂詞param is number
。 相反,您需要編寫編譯器認為可分配給T
(和number
)的類型。 所以我們將使用交集param is T & number
。
所以這里是:
function isNumber<T extends number extends T ? unknown : number>(
param: T
): param is number & T {
return typeof param === "number"
}
讓我們測試一下:
isNumber("oops"); // error, Argument of type 'string' is
// not assignable to parameter of type 'number'.
isNumber(Math.random() < 0.5 ? "abc" : 123); // okay
isNumber(14); // okay
看起來不錯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.