TypeScript中判断never

787 阅读1分钟

never extends never ?

群里看到一个有趣的问题:

// a is true
type a = never extends never ? true : false;

// b is never
type isNever<T> = T extends never ? true : false
type b = isNever<never>

想了解为什么会这样,需要理解下TypeScript: Documentation - Conditional Types (typescriptlang.org)

因为never是一个特殊的联合类型,它没有任何一个成员,而根据Distributive Conditional Types,联合类型作为泛型传入后,会分开计算和合起来,例如:

// c = isNever<string> | isNever<number>
type c = isNever<string | number>

因此当输入是never时,因为他一个成员都没有,自然也不需要计算了,直接返回never

不想使用Distributive Conditional Types时,可以在泛型前后加上括号即可:

type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never;

// 'StrArrOrNumArr' is no longer a union.
// type StrArrOrNumArr = (string | number)[]
type StrArrOrNumArr = ToArrayNonDist<string | number>;

参考

Generic conditional type T extends never ? 'yes' : 'no' resolves to never when T is never. · Issue #31751 · microsoft/TypeScript (github.com)