过滤对象的键,以便仅返回指向数组的键(而不是通过“ keyof”显示所有键)

时间:2018-07-11 14:54:49

标签: typescript

对于student.ts

type Student = {
    name: string,
    marks: string[],
    subjects: string[]
}

如何获取ArrayKey<Student>,使其仅返回指向任何数组的键,此处应指向'marks'|'subjects'

我的尝试

type ArrayKey<T, Key extends keyof T = keyof T> = T[Key] extends any[] ? Key : never;

let c: ArrayKey<Student> = 'marks';

但是会引发错误[ts] Type '"marks"' is not assignable to type 'never'

1 个答案:

答案 0 :(得分:3)

您已经接近了,但是您的代码要求开发人员指定Key,这是您要输出的内容。您可以改为使用mapped types遍历T的键,然后使用条件类型来标识具有数组值属性的键。像这样:

type ArrayKey<T> = { [Key in keyof T]: T[Key] extends any[] ? Key : never }[keyof T];

type Student = {
  name: string,
  marks: string[],
  subjects: string[]
}

let c: ArrayKey<Student> = 'marks'; // okay

另一种更接近原始定义的方法是使用distributive conditional typeK的成分上分配条件:

type ArrayKey<T, Key extends keyof T = keyof T> = 
   Key extends any ? T[Key] extends any[] ? Key : never : never

这也可以,但是K必须是裸类型参数,并且Key extends any可能会令人困惑(分布式条件类型有点令人惊讶),并且它滥用了{{1}的默认值},因此我不推荐使用。 hacky少,但仍使用分布式条件类型:

K

这不会滥用默认参数,这很好。尽管如此,分布式条件类型的惊喜因素仍然成立,因此总体上我仍然推荐映射类型的解决方案。


希望有帮助。祝你好运!