You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:10:13