首页 > 解决方案 > 使用 TypeScript 定义类型的键作为属性类型

问题描述

对不起,令人困惑的标题。这是我的问题。

我有一个类型:

type Person = {
    firstName?: string;
    middleName?: string;
    lastName?: string;
}

假设我想动态获取这些属性之一。

const getPersonAttribute = (field: string) => {
    return person[field];
}

这会引发 TS 错误(关于隐式类型<string><any>不能是 type 的索引Person),所以为了让它工作,我这样做:

const getPersonAttribute = (field: 'firstName' | 'middleName' | 'lastName') => {
    return person[field];
}

有一个更好的方法吗?以某种方式动态获取类型的属性?

标签: typescripttypescript-typings

解决方案


您只想要keyof,如此处所述

declare const person: Person;
const getPersonAttribute = (field: keyof Person) => {
  return person[field]; // okay
}
// const getPersonAttribute: (field: keyof Person) => string | undefined

在这种情况下,返回类型getPersonAttributestring | undefined。如果你有不同类型的属性Person(比如一个age类型number),

type Person = {
  firstName?: string;
  middleName?: string;
  lastName?: string;
  age?: number;
}

那么返回类型将是、 和 的并集string,这对于您的用例可能不够具体:numberundefined

// const getPersonAttribute: (field: keyof Person) => string | number | undefined
const personLastName = getPersonAttribute("lastName"); // string | number | undefined
const personAge = getPersonAttribute("age"); // string | number | undefined

如果您希望getPersonAttribute()的输出类型依赖于特定的输入键,那么您需要在输入键类型中使函数泛型:

const getPersonAttributeGen = <K extends keyof Person>(field: K) => {
  return person[field]; // okay
}
// const getPersonAttributeGen: 
// <K extends "firstName" | "middleName" | "lastName" | "age">(field: K) => Person[K]

这会产生 type 的输出Person[K],一种查找类型(在上面的同一链接中记录):

const personLastNameBetter = getPersonAttributeGen("lastName"); // string | undefined
const personAgeBetter = getPersonAttributeGen("age"); // number | undefined

Playground 代码链接


推荐阅读