【问题标题】:Type based on another field within an array基于数组中的另一个字段键入
【发布时间】:2021-07-16 12:15:18
【问题描述】:

我希望以下示例产生类型错误:

interface Person {
  age: number;
  name: string;
  birthday: Date;
}

interface Grid<T> {
  columns: {
    field: keyof T;
    formatter: (value: T[keyof T]) => string;
  }[];
}

function draw<T>(grid: Grid<T>) {}

draw<Person>({
  columns: [
    {
      field: "age",
      formatter: (value: number) => "",
    },
    {
      field: "name",
      formatter: (value: number) => "", // <-- this parameter should be a `string`! However, TS allows this because `T[keyof T]` matches.
    },
  ],
});

我应该更改格式化函数的类型签名以使其参数与字段的类型匹配?

【问题讨论】:

标签: typescript


【解决方案1】:

映射类型可以:

interface Person {
  age: number;
  name: string;
  birthday: Date;
}

// here using mapped types 
type Grid<T, Out> =
    {
        columns: {
            [K in keyof T]: 
                {
                    field: K,
                    formatter: (value: T[K]) => Out
                }
        }[keyof T][]
    }

// pay attention that it has second argument which mean the output of the formatting
function draw<T>(grid: Grid<T, string>) {}

draw<Person>({
  columns: [
    {
      field: "age",
      formatter: value => "" // value inferred as number 
    },
    {
      field: "name",
      formatter: (value: number) => "", // error as expected
    },
  ],
});

playground

一些解释:

type Grid<T, Out> =
    {
        columns: {
            [K in keyof T]: 
                {
                    field: K,
                    formatter: (value: T[K]) => Out
                }
        }[keyof T][]
    }
  • 我们映射了 T K in keyof T 的键
  • 在每次迭代中,我们都会创建一个对象,该对象需要密钥 K,并且需要从 T[K] 到定义的输出类型的函数
  • [keyof T] 表示我们希望通过映射类型从创建的对象中获取所有值,结果我们将获得所有对象与字段和格式化程序道具的联合

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-09-06
  • 2021-06-27
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多