【问题标题】:How to infer object key type based on another key in Typescript如何根据 Typescript 中的另一个键推断对象键类型
【发布时间】:2022-08-09 03:30:46
【问题描述】:

我有一个带有键值对的类型,其中键是 React 组件名称,值是它们作为道具的值。我要做的是键入一个包含类型字段的类型数组,这也是组件的确切名称,以及使用组件值类型的gettersetter 函数。


type ElementValues = {
    text: string,
    checkbox: boolean
}

type ElementType = keyof ElementValues

type Value<Type extends ElementType> = ElementValues[Type]

type Test = {
    [Type in ElementType]: {
    type: Type
    getter: () => Value<Type>
    setter: (value: Value<Type>) => any
}}[ElementType]

const testList: Array<Test> = [{
    type: \'checkbox\',
    getter: () => \'test,
    setter: (value) => ({ })
}]

我能得到的是包含不关心给定组件名称并将所有可能的组件值类型作为 setter 和 getter 参数/返回类型的元素的数组。

在上面的例子中,getter 应该需要boolean,就像复选框值一样,setter 的值类型应该是boolean,而不是boolean | string

    标签: typescript generics type-inference


    【解决方案1】:

    以下将做的伎俩。只需使用discriminated unions。这样,数组元素将由type 字段(textcheckbox)区分。

    type ElementValues = {
      text: string,
      checkbox: boolean
    }
    
    type ElementType = keyof ElementValues
    
    type Value<Type extends ElementType> = ElementValues[Type]
    
    type Test<Type extends ElementType> = {
      type: Type
      getter: () => Value<Type>
      setter: (value: Value<Type>) => any
    }
    
    // Here - Discriminated Unions
    type Elements =
      | Test<'checkbox'>
      | Test<'text'>
    
    const testList: Array<Elements> = [
      {
        type: 'text',
        getter: () => 'test1',
        setter: (value) => ({ })
      },
      {
        type: 'checkbox',
        getter: () => true,
        setter: (value) => ({ })
      }
    ]
    

    【讨论】:

    • 这与code in the question 有何不同?
    • 我已经编辑了答案,以准确指出最重要的变化是代码本身的注释。
    • 我看到代码有点不同。但结果看起来完全一样。
    • 我懂了。看起来我只是“混淆”了一点。 OF 在他/她自己的问题中一直有答案。 (:
    • 他可能正在寻找其他东西,但无法准确地告诉我们他想要什么。
    【解决方案2】:

    似乎添加辅助类型Elements 解决了这个问题。 基于@lepsch 答案:

    type ElementValues = {
      text: string,
      checkbox: boolean
    }
    
    type ElementType = keyof ElementValues
    
    type Value<Type extends ElementType> = ElementValues[Type]
    
    type Test<Type extends ElementType> = {
      type: Type
      getter: () => Value<Type>
      setter: (value: Value<Type>) => any
    }
    
    type Elements = {
        [Type in ElementType]: Test<Type>
    }[ElementType]
    
    const testList: Array<Elements> = [
      {
        type: 'text',
        getter: () => 'test',
        setter: (value) => ({ })
      },
      {
        type: 'checkbox',
        getter: () => true,
        setter: (value) => ({ })
      }
    ]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-19
      • 2022-01-05
      • 1970-01-01
      • 2021-06-09
      • 2020-12-28
      • 2022-12-18
      • 2022-06-10
      • 2019-07-03
      相关资源
      最近更新 更多