如何推断对象的类型 属性

How to infer the type of an object's property

我有以下代码,我想推断对象 属性 的类型。如您所见,在我的示例中 v 的推断类型是 {}。 我如何编写 myValue 以便 Typescript 在编译时推断出 C


const myValue = <T1, T2>(prop: string, obj: T1): T2 => {
  return obj[prop]
}

interface C {
  readonly c: string
}

interface TestInt {
  readonly a: string
  readonly b: number
  readonly c: C
}

const test: TestInt = {
  a: 'a',
  b: 1,
  c: {
    c: 'c',
  },
}

const v = myValue('c', test) // const v: {}

当您具有要推断的类型的实际值时,类型参数推断效果最佳。将 T2 作为函数的 return 值的类型可能会出现问题。除非您在 期望 return 值的类型为 C 的上下文中调用 myValue(),否则编译器将推断 C 对于它...从 return 值推断类型参数称为 contextual typing,不幸的是在 const v = myValue(...) 中,v 没有上下文类型.它可以是任何东西。

那么你实际上有哪些类型的值?由于您使用 propobj 参数调用 myValue(),因此首先要尝试为 obj 提供一个通用类型,如 T 并提供 prop 另一种通用类型,如 K... 并分别从 objprop 推断出 TK

请注意,您打算 prop 应该是 obj 的键之一,因此您在 K 的类型上有一个自然的 constraint,即它应该扩展 keyof T

最后,您函数的 return 类型可以从其他类型派生。它的意思是 T 的 属性 的类型,其键是 K。可以表示为 T[K] (a lookup type).

这是函数的最终版本:

const myValue = <T, K extends keyof T>(prop: K, obj: T): T[K] => {
    return obj[prop];
}

请注意该函数与 documentation for keyof and lookup types 中提到的 getProperty() 函数之间的相似性。唯一的区别是参数的顺序(好吧,事实上 return 类型是推断的而不是注释的……我猜是函数名)。

当我们使用 myValue() 的定义时,我们得到:

interface C {
    readonly c: string
}

interface TestInt {
    readonly a: string
    readonly b: number
    readonly c: C
}

const test: TestInt = {
    a: 'a',
    b: 1,
    c: {
        c: 'c',
    },
}

const v = myValue('c', test) // const v: C

如你所愿。

希望对您有所帮助;祝你好运!