用于推断的 never[] 和 any[] 的 Typescript UnpackArrayType 工作不正确
Typescript UnpackArrayType for inferred never[] and any[] works incorrectly
我正在尝试使用 (infer R)[]
作为 never
和 any
类型来解包数组。
type UnpackArrayType<T> = [T] extends [(infer R)[]] ? R : false;
但结果出乎意料:Typescript 既没有从“else”(非数组条件)中转换为 false,也没有检测到推断类型 R。
type UnpackArrayType<T> = [T] extends [(infer R)[]] ? R : false; // false type used as non-array-marker
type UA<T> = UnpackArrayType<T>; // just alias
type TypeTesting = {
"never": UA<never>, // unknown - incorrect
"never[]": UA<never[]>, // never - correct
"any": UA<any>, // unknown - incorrect
"any[]": UA<any[]>, // any - correct
"unknown": UA<unknown>, // false - correct
"unknown[]": UA<unknown[]>, // unknown - correct
"null": UA<null>, // false - correct
"null[]": UA<null[]>, // null - correct
"undefined": UA<undefined>, // false - correct
"undefined[]": UA<undefined[]>, // undefined - correct
"number": UA<number>, // false - correct
"number[]": UA<number[]>, // number - correct
}
为什么 any
和 never
类型解包为 unknown
?
extends
测试类型之间的关系,然后尝试提取推断的位置。
any
和 never
都有 属性 它们是任何其他类型的子类型(any
更奇怪,因为它也是任何类型的基类型其他类型)。所以问 never extends T
或 any extends T
的问题对于任何类型 T
都将 return 为真。
回答完扩展问题后,我们可以考虑推理问题,因为没有好的方法从 any
或 never
中提取 [(infer R)[]]
中的 R
你最终得到 unknown
.
您可以对这两种通用类型的子类型进行特殊处理:
type UnpackArrayType<T> =
[T] extends [never] ? false: // nothing extends never except never itslef
[T & 1] extends [T & 2]? false : // T & 1 extends T & 2 will only be true if T is any and the & 1 and & 2 get absorbed into any
[T] extends [(infer R)[]] ? R : false; // false type used as non-array-marker
type UA<T> = UnpackArrayType<T>; // just alias
type TypeTesting = {
"never": UA<never>, // false - correct
"never[]": UA<never[]>, // never - correct
"any": UA<any>, // false - correct
"any[]": UA<any[]>, // any - correct
"unknown": UA<unknown>, // false - correct
"unknown[]": UA<unknown[]>, // unknown - correct
"null": UA<null>, // false - correct
"null[]": UA<null[]>, // null - correct
"undefined": UA<undefined>, // false - correct
"undefined[]": UA<undefined[]>, // undefined - correct
"number": UA<number>, // false - correct
"number[]": UA<number[]>, // number - correct
}
注意:要从已知为数组的类型中提取元素类型,您还可以使用 T[number]
我正在尝试使用 (infer R)[]
作为 never
和 any
类型来解包数组。
type UnpackArrayType<T> = [T] extends [(infer R)[]] ? R : false;
但结果出乎意料:Typescript 既没有从“else”(非数组条件)中转换为 false,也没有检测到推断类型 R。
type UnpackArrayType<T> = [T] extends [(infer R)[]] ? R : false; // false type used as non-array-marker
type UA<T> = UnpackArrayType<T>; // just alias
type TypeTesting = {
"never": UA<never>, // unknown - incorrect
"never[]": UA<never[]>, // never - correct
"any": UA<any>, // unknown - incorrect
"any[]": UA<any[]>, // any - correct
"unknown": UA<unknown>, // false - correct
"unknown[]": UA<unknown[]>, // unknown - correct
"null": UA<null>, // false - correct
"null[]": UA<null[]>, // null - correct
"undefined": UA<undefined>, // false - correct
"undefined[]": UA<undefined[]>, // undefined - correct
"number": UA<number>, // false - correct
"number[]": UA<number[]>, // number - correct
}
为什么 any
和 never
类型解包为 unknown
?
extends
测试类型之间的关系,然后尝试提取推断的位置。
any
和 never
都有 属性 它们是任何其他类型的子类型(any
更奇怪,因为它也是任何类型的基类型其他类型)。所以问 never extends T
或 any extends T
的问题对于任何类型 T
都将 return 为真。
回答完扩展问题后,我们可以考虑推理问题,因为没有好的方法从 any
或 never
中提取 [(infer R)[]]
中的 R
你最终得到 unknown
.
您可以对这两种通用类型的子类型进行特殊处理:
type UnpackArrayType<T> =
[T] extends [never] ? false: // nothing extends never except never itslef
[T & 1] extends [T & 2]? false : // T & 1 extends T & 2 will only be true if T is any and the & 1 and & 2 get absorbed into any
[T] extends [(infer R)[]] ? R : false; // false type used as non-array-marker
type UA<T> = UnpackArrayType<T>; // just alias
type TypeTesting = {
"never": UA<never>, // false - correct
"never[]": UA<never[]>, // never - correct
"any": UA<any>, // false - correct
"any[]": UA<any[]>, // any - correct
"unknown": UA<unknown>, // false - correct
"unknown[]": UA<unknown[]>, // unknown - correct
"null": UA<null>, // false - correct
"null[]": UA<null[]>, // null - correct
"undefined": UA<undefined>, // false - correct
"undefined[]": UA<undefined[]>, // undefined - correct
"number": UA<number>, // false - correct
"number[]": UA<number[]>, // number - correct
}
注意:要从已知为数组的类型中提取元素类型,您还可以使用 T[number]