Я хочу написать служебный метод, который ищет любую карту, и я хочу, чтобы тип ключа соответствовал типу предиката.
Как будет выглядеть соответствующая подпись метода, если она есть?
Например, я бы хотел обобщить эту подпись:
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
}
Вызывает ошибку компиляции (нажмите, чтобы увеличить) в конце использования:
Использование 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:
Тем не менее, обходной путь для этой проблемы приветствуется, если таковой существует.