Общий метод, который принимает оба отображения {[key: string]: V} и {[key: number]: V} - PullRequest
0 голосов
/ 17 апреля 2019

Я хочу написать служебный метод, который ищет любую карту, и я хочу, чтобы тип ключа соответствовал типу предиката.

Как будет выглядеть соответствующая подпись метода, если она есть?

Например, я бы хотел обобщить эту подпись:

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

Я пробовал это, но это дает мне ошибку компилятора (вероятно, потому что "расширяет"), хотя лучше всего описывает то, что я думаю о :

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

Следующее позволяет использовать оба типа карт, но не полностью. То есть он позволяет использовать спортивные методы предикатов (например, key.startsWith (..)), которые отсутствуют в числах, но работают из-за автоматического преобразования типов, но запрещает использование числовых операторов, таких как> или <для числовых ключей: </p>

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

Следующее позволяет использовать оба типа карт, но запрещает использование таких методов, как string.startsWith (..), хотя и допускает математические операторы, такие как> и <(что не имеет смысла), также если будет работать, ему не требуется принудительное соответствие типа ключа типу предиката. </p>

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

Edit: Предлагаемое решение:

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

Вызывает ошибку компиляции (нажмите, чтобы увеличить) в конце использования: compile error with suggested solution Использование Typescript 2.7.2


Edit: Также попробовал это:

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

но тогда, если я сделаю:

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)

Edit:

Возникли проблемы с Typescript:

Похоже, что есть открытый запрос Pull для машинописного текста 3.x:

Тем не менее, обходной путь для этой проблемы приветствуется, если таковой существует.

1 Ответ

0 голосов
/ 17 апреля 2019

должно выглядеть так

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