【问题标题】:why do I have to add 'keyof' in front of 'any' type when use type mapping为什么在使用类型映射时必须在“any”类型前面添加“keyof”
【发布时间】:2019-09-26 12:55:30
【问题描述】:

我想创建新类型,而不是转换特定类型,下面是我的代码:

type CustomMapped<K extends any , T> = {                         //can't compile
    [P in K]: T
};

它没有编译,错误是:

类型 K 不能分配给类型 'string |号码 |符号'

所以我必须在任何前面添加keyof

type CustomMapped<K extends keyof any , T> = ...                 //can compile

我很困惑,如果我将代码重写为:

type CustomMapped<K extends string | number | symbol, T> = {    //also compile
    [P in K]: T
};

它可以编译,所以这意味着类型 K 可分配给类型 string | number | symbol

那么为什么原来的错误说 Type K not 可分配给类型 string | number | symbol,为什么我添加了 keyof 然后就可以了?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    in 运算符用于创建 mapped types

    它期望字符串、数字或符号的联合能够有效地迭代。如文档所示:

    type Keys = 'option1' | 'option2';
    type Flags = { [K in Keys]: boolean };
    

    K 将在第一次“迭代”时变为 option1,在第二次“迭代”时变为 option2。但是,如果 Keys 是一个对象,这将不起作用。

    type Keys = { option1: any; option2: any };
    type Flags = { [K in Keys]: boolean }; 
    //                   ^^^^
    // Type 'Keys' is not assignable to type 'string | number | symbol'.
    

    因为Keys 不是要迭代的stringnumbersymbol,而是一个对象。由于我们要遍历键,这可以通过 keyof 运算符返回 'option1' | 'option2' 来解决。

    通过您的示例,您可以使用 [P in keyof K] 更新它,这将评估为 [P in 'option1' | 'option2'] 并按预期工作:

    type CustomMapped<K extends any, T> = { [P in keyof K]: T };
    

    【讨论】:

    • 我有点明白你的意思,但keyof any 是什么意思? any 不是一个对象,不是吗?
    • @TitianCernicova-Dragomir 我想我困惑的根源是这个问题,冷你看看stackoverflow.com/questions/58110690/…
    • @secondimage 我认为 skovy 很好地解释了它,这就是它的实现方式 in 之后的类型可证明必须是 keyof any 的子类型(即 string | number | symbol . 没有什么能做这只是一个硬编译器要求。如果你要映射到any 编译器应该做什么,它可能必须映射到string | number | symbol 所以为什么不确保any 没有进入那里是我的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多