接受{[key:string]:V}和{[key:number]:V}映射的通用方法

时间:2019-04-17 09:23:55

标签: typescript typescript-generics

我想编写一个实用程序方法来搜索任何地图,并且我要强制键类型与谓词类型匹配。

如果有的话,合适的方法签名会是什么样?

例如,我想对此签名进行概括:

someKey<K extends string|number, V>(object: { [key: K]: V }, predicate: (key: K) => boolean): boolean {
   // ....
}

我已经尝试过了,但是它给了我一个编译器错误(可能是因为“扩展”),尽管它最能描述我的想法

someKey<V>(object: { [key: string]: V }|{ [key: number]: V }, predicate: (key: string) => boolean): boolean {
   // ....
}

以下内容适用于两种类型的地图,但不完全适用。即它允许数字中不存在谓词运动方法(如key.startsWith(..)),但由于自动类型转换而起作用,但它禁止对数字键使用数字运算符,如>或<: >

someKey<V>(object: { [key: string]: V }|{ [key: number]: V }, predicate: (key: string|number) => boolean): boolean {
   // ....
}

以下内容允许同时使用两种类型的地图,但禁止使用诸如string.startsWith(..)之类的方法,尽管它允许使用诸如>和<之类的数学运算符(这在某种意义上没有意义),会起作用,它没有强制键类型与谓词类型匹配。

someKey<K extends string|number, V>(object: { [key in keyof K]: V }, predicate: (key: K) => boolean): boolean {
   return true; // your actual logic
}

编辑: 建议的解决方案:

someKey<M extends { [key: string]: any } | { [key: number]: any }>
       (object: M, predicate: (key: keyof M) => boolean): boolean {
  return true; // body goes here
}

在使用端引发编译错误(单击放大): compile error with suggested solution 使用打字稿2.7.2


编辑: 还尝试了这个:

const testMap2 = {
    1: 'a',
    2: 'bb',
    3: 'ccc',
    4: 'dddd',
    5: 'eeeee',
  };

  it('#someKey should return true if found', () => {
    expect(Utility.someKey(testMap2, key => key > 1)).toBe(true);
  });

但是如果我这样做:

(parameter) key: "1" | "2" | "3" | "4" | "5"
Operator '>' cannot be applied to types 'string' and 'number'.ts(2365)

它说:

{{1}}

编辑:

存在针对Typescript的问题:

好像有一个开放的请求打字稿3.x:

如果存在此问题,仍然可以解决此问题。

1 个答案:

答案 0 :(得分:0)

应该是这样

function someKey<K extends string|number, V>(object: { [key in keyof K]: V }, predicate: (key: K) => boolean): boolean {
    return true; // your actual logic
 }