【问题标题】:Typescript UnpackArrayType for inferred never[] and any[] works incorrectly推断 never[] 和 any[] 的 Typescript UnpackArrayType 工作不正确
【发布时间】:2022-01-03 11:23:36
【问题描述】:

我尝试使用 (infer R)[]neverany 类型解包数组。

type UnpackArrayType<T> = [T] extends [(infer R)[]] ? R : false;

但结果出乎意料:Typescript 既没有从“else”(非数组条件)强制转换为 false,也没有检测到推断的类型 R。

demo link

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
}

为什么anynever 类型解包为unknown

【问题讨论】:

  • anynever 都是任何其他类型的子类型,这就是为什么它们可以分配给任何其他值。因此,无论X 是什么,问问题never extends X 总是会返回true。
  • @TitianCernicova-Dragomir 期待您的回答,提供更多解释和示例

标签: typescript extends inferred-type


【解决方案1】:

extends 测试类型之间的关系,然后尝试提取推断的位置。

anynever 都具有它们是任何其他类型的子类型的属性(any 更奇怪,因为它也是任何其他类型的基本类型)。所以问never extends Tany extends T 的问题对于T 的任何类型都会返回true。

在回答完扩展问题之后,我们可以考虑推理问题吗?因为没有好的方法可以从anynever 中提取[(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
}

Playground Link

注意:要从已知为数组的类型中提取元素类型,您还可以使用T[number]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-04
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多