如何修复Object.entries中字符串索引CustomStorageFor的TypeScript错误?
修复TypeScript中
initStorage()的索引错误 在之前的问题之后,新类型CustomStorageFor引发了错误,报错信息:
Type 'string' cannot be used to index type 'CustomStorageFor
'
错误代码行:
this.storage[key] = this.createStore(key, value)
完整代码如下:
type CustomStorageFor<T> = { [K in keyof T]: CustomStore<T[K]> } & { [key: string]: CustomStore<T> } type CustomStore<T> = { value: T, init: (value: T) => void; set: (value: T) => void; } class LiveStorage<T extends object> { private defaultStorage: T storage: CustomStorageFor<T> constructor(defaultStorage: T) { this.defaultStorage = defaultStorage this.storage = {} as CustomStorageFor<T> this.initStorage() } private async initStorage() { Object.entries(this.defaultStorage).forEach(([key, value]) => { // key: string, value: any this.storage[key] = this.createStore(key, value) }) } private createStore<ValueType>(key: string, value: ValueType): CustomStore<ValueType> { //... } }
问题原因
Object.entries()返回的key类型为string,但CustomStorageFor<T>的类型定义存在冲突:
- 映射类型
{ [K in keyof T]: CustomStore<T[K]> }的键是keyof T(可能包含字符串、数字或符号),对应的值类型是CustomStore<T[K]> - 额外添加的
[key: string]: CustomStore<T>要求所有字符串键的值类型必须是CustomStore<T>,这和映射类型的值类型不兼容,导致TypeScript无法确认string类型的key可以安全索引CustomStorageFor<T>。
解决方法
方法1:修正CustomStorageFor的类型定义
调整索引签名的类型,使其覆盖映射类型的成员:
// 用unknown兼容所有可能的CustomStore类型 type CustomStorageFor<T> = { [K in keyof T]: CustomStore<T[K]> } & Record<string, CustomStore<unknown>>
如果不需要额外的字符串索引,直接去掉该部分,仅保留映射类型:
type CustomStorageFor<T> = { [K in keyof T]: CustomStore<T[K]> }
方法2:断言key为keyof T
因为defaultStorage的键本质就是keyof T,可以通过类型断言告诉TypeScript该键合法:
private async initStorage() { Object.entries(this.defaultStorage).forEach(([key, value]) => { this.storage[key as keyof T] = this.createStore(key, value) as CustomStore<T[keyof T]> }) }
方法3:使用for...in循环替代Object.entries
for...in循环能保留键的原始类型keyof T,避免类型丢失:
private async initStorage() { for (const key in this.defaultStorage) { if (Object.prototype.hasOwnProperty.call(this.defaultStorage, key)) { const value = this.defaultStorage[key]; this.storage[key] = this.createStore(key, value); } } }
内容的提问来源于stack exchange,提问作者Viewed
相关产品推荐
相关产品推荐

