【问题标题】:Infer the key type of the array object推断数组对象的键类型
【发布时间】:2022-07-19 20:55:06
【问题描述】:

我有下一个例子

type C = [
    {name: 'a'},
    {name: 'b'},
    {name: 'c'},
]

我想根据上面描述的C类型推断出一个新类型SomeType,就像这样

const a: SomeType<C> = {
    a: () => {},
    b: () => {},
    c: () => {},
}

这样就可以检查所有键。下面的例子一定是无效的

const a: SomeType<C> = {
    a: () => {},
    b: () => {},
    // Error. "c" is not defined
}

我已尝试像在 playground 中那样解决我的问题,但我的解决方案并未检查所有键是否存在

【问题讨论】:

    标签: typescript type-inference


    【解决方案1】:

    你需要一个mapped type 来从数组类型映射到你想要的类型:

    type SomeType<T extends Array<{ name: string }>> = {
      [P in T[number]['name']]: () => void
    }
    

    Playground Link

    【讨论】:

      【解决方案2】:

      这是一种方法:

      type SomeType<T extends { [k: number]: { name: string } }> =
          Record<T[number]['name'], () => void>;
      

      它接受T constrained 到具有数字index signature 的类型(例如数组),其元素具有name 类型的name 属性string

      它计算出一个类型,其键是string-assignable name 属性(使用T[number]['name'],一系列indexed access types),其值类型是一个函数(我选择了() =&gt; void,但是你可能有一个更具体的类型你关心)。这使用the Record&lt;K, V&gt; utility type 表示具有K 类型的键和V 类型的值的对象类型。

      让我们试试吧:

      const ports: SomeType<C> = { // error, missing b and c
          a: () => { },
      }    
      
      const ports2: SomeType<C> = {
          unknownkey: () => { }, // error, unknown key in object literal 
                                 // (note, only errors for object literal)
      }
      
      const ports3: SomeType<C> = { // okay
          a: () => { },
          c: () => { },
          b: () => { },
      }
      

      看起来不错!

      Playground link to code

      【讨论】:

        猜你喜欢
        • 2021-07-24
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 2020-01-21
        • 1970-01-01
        • 1970-01-01
        • 2019-08-12
        • 2020-07-19
        相关资源
        最近更新 更多