【问题标题】:Typescript - Use generics and parameters values to set a typeTypescript - 使用泛型和参数值来设置类型
【发布时间】:2021-01-21 09:58:38
【问题描述】:

我想要一种方法来拥有一个具有单个泛型的接口,其中一个属性是keyof T,另一个是正确的T[keyof T],传递给第一个属性。

下面的代码几乎满足了这个要求,正确输入了第一个属性(field):

interface RandomType {
    foo: string;
    bar: number;
    baz: boolean;
}

type Typer<T = Record<string, any>> = {
    field: keyof T,
    value: T[any]
}

const param: Typer<RandomType> = {
    field: 'baz',
    value: 'foo'
}

但是,我需要根据field 的值输入value

在前面的例子中,它应该触发一个类型错误,因为RandomType['baz']boolean

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    您希望Typer&lt;T&gt; 成为T 中每个字段的字段/值对的union。您可以通过多种方式做到这一点。例如:

    type Typer<T> = { [K in keyof T]: {
        field: K,
        value: T[K]
    } }[keyof T];
    

    这里我们用mapping overT中的属性来获取一个新对象,它的值是你想要的类型,然后立即looking up它的所有值。

    您可以验证Typer&lt;RandomType&gt; 是您要查找的内容:

    type TyperRandomType = Typer<RandomType>
    /* type TyperRandomType = {
        field: "foo";
        value: string;
    } | {
        field: "bar";
        value: number;
    } | {
        field: "baz";
        value: boolean;
    } */
    

    然后您的示例给出了您期望的错误:

    const param: Typer<RandomType> = {
        field: 'baz',
        value: 'foo'
    }; // error!
    // Types of property 'value' are incompatible.
    // Type 'string' is not assignable to type 'boolean'
    

    Playground link to code

    【讨论】:

      【解决方案2】:

      这会做你想做的事,但现在你必须指定键两次:

      type Typer<T, K extends keyof T> = {
          field: K,
          value: T[K]
      }
      
      const param: Typer<RandomType, 'baz'> = {
          field: 'baz',
          value: 'foo' // Type 'string' is not assignable to type 'boolean'. ts(2322)
      }
      

      我认为 TS 存在一个未解决的问题,可以只指定一些泛型并推断其余的,以便 Typer&lt;RandomType&gt; 可以工作。

      【讨论】:

      猜你喜欢
      • 2021-12-06
      • 2020-11-10
      • 2016-12-05
      • 1970-01-01
      • 2011-02-28
      • 2021-06-14
      • 2021-07-10
      • 2022-11-29
      • 2019-06-27
      相关资源
      最近更新 更多