如何指定 Typescript 泛型 T[K] 是数字类型?

Jos*_*ang 5 generics typescript keyof

我有一个简单的 Typescript 函数,如下所示:

function getProperty<T, K extends keyof T>(obj: T, key: K): number {
  return obj[key]; // This line is not compiling.
  // Typescript will yell: "Type 'T[K]' is not assignable to type 'number'."
}
Run Code Online (Sandbox Code Playgroud)

我的用法如下:

const someObj = {
  myValue: 123,
  otherProperty: '321'
}

getProperty(someObj, 'myValue')
Run Code Online (Sandbox Code Playgroud)

我不知道 的结构someObj会是什么。

我的问题是:如何T[K]静态指定数字类型?

T.J*_*der 2

我不知道 的结构someObj会是什么。

那么 TypeScript 无法真正帮助你解决这个问题。TypeScript 的类型检查是在编译时完成的。如果 的结构仅在运行someObj时已知,则 TypeScript 无法以类型安全的方式访问该结构。您需要知道编译时的属性键和这些属性的可能值。

例如:在您的示例中,属性名称是字符串,属性值是字符串或数字(但不是布尔值或对象等)。您可以声明一个由字符串索引的类型(因为所有属性名称最终都是字符串或符号,在本例中是字符串),其中属性值是数字或字符串:

declare type SomeObjType = {
    [key: string]: number | string
};
Run Code Online (Sandbox Code Playgroud)

然后getProperty是:

function getProperty<T extends SomeObjType>(obj: T, key: string): number | string {
  return obj[key];
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它(在这种情况下,我用来JSON.parse模拟从程序范围之外接收此数据):

const someObj: SomeObjType = JSON.parse(`{
  "myValue": 123,
  "otherProperty": "321"
}`);

console.log(getProperty(someObj, 'myValue'));
console.log(getProperty(someObj, 'otherProperty'));
Run Code Online (Sandbox Code Playgroud)

在操场上

但这并没有给你带来太多好处,并且消除了属性值不是数字或字符串的可能性。

您可能只需要使用object

function getProperty(obj: object, key: string) {
  return obj[key];
}

const someObj = JSON.parse(`{
  "myValue": 123,
  "otherProperty": "321"
}`);

console.log(getProperty(someObj, 'myValue'));
console.log(getProperty(someObj, 'otherProperty'));
Run Code Online (Sandbox Code Playgroud)

在操场上