Определение TypeScript для Object.entries
перегружено, но обе перегрузки явно используют строку в качестве типа ключа. От lib/lib.es2017.object.d.ts
:
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries(o: {}): [string, any][];
Я уверен, что для этого есть веская причина. :-) Но вы можете определить свой собственный entries
, который не использует string
:
// Our `entries` function
function entries<T>(o: T): [keyof T, T[keyof T]][] {
return Object.entries(o) as unknown as [keyof T, T[keyof T]][];
}
Тогда это работает:
for (const [name, hex] of entries(myColors)) {
// type of `name` is `Color` now
}
Если продолжить, я обнаружил, что если добавить следующее объявление:
interface ObjectConstructor {
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: T): [keyof T, T[keyof T]][];
}
При этом ваш оригинальный код работает так, как вы ожидали:
for (const [name, hex] of Object.entries(myColors)) {
// type of `name` is `Color` now
}
(Я дважды проверил это с реальным компилятором, а не только с игровой площадкой, имея const n: Color = name;
в теле цикла. TypeScript жалуется на это без объявления, но с объявлением, что он счастлив.)
Но , некоторые проблемы в списке проблем TypeScript заставляют меня думать, что определение может вызвать проблемы с другими вещами, которые вы передаете Object.entries
, в частности этот и этот комментарий . Таким образом, вы можете захотеть иметь отдельную функцию (которая, скорее всего, уберет JIT) и использовать ее там, где это необходимо.