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

TypeScript多语言字典字符串索引访问类型报错排查

TypeScript多语言字典访问类型错误问题解决

问题背景

我正在为一款应用开发多语言字典,声明了如下TypeScript类型:

type SingleDictionaryEntry = {
    [key: string]: string
}

type Entry = {
    [key: string]: SingleDictionaryEntry | string
}

type Dict = {
    [key: string]: Entry
}

字典实例定义如下:

const Dictionary: Dict = {
    menu: {
        companies: 'Companies',
        clients: 'Clients',
        requests: 'Requests',
        sites: 'Sites'
    },
    companies: {
        list: 'Companies',
        new: 'Add New Company',
        edit: 'Edit',
        delete: 'Delete',
        table: {
            title: 'Title',
            type: 'Type',
            email: 'E-Mail',
            address: 'Address',
            city: 'City',
            telephone: 'Telephone',
            cellular: 'Cellular'
        }
    }
}

当通过以下代码访问翻译内容时(注:原代码存在笔误,column修正为field):

const fields: Array<string> = ['title', 'type', 'email']
const dictionaryRoot: string = 'companies'

return (
    <>
    {
        fields.map((field) => (
            <strong>{Dictionary[dictionaryRoot].table[field] ?? field}</strong>
        ))
    }
    </>
)

出现错误提示:

Element implicitly has any 'type' because expression of type 'string' can't be used to index type 'string | SingleDictionaryEntry'. No index signature with a parameter of type 'string' was found on type 'string | SingleDictionaryEntry'.

错误原因

你的Entry类型定义中,属性值是SingleDictionaryEntry | string的联合类型。当访问Dictionary[dictionaryRoot].table时,TypeScript无法确定table到底是字符串还是嵌套字典对象——因为Entry的每个键都可能对应两种类型之一。所以尝试用字符串类型的field去索引table时,TypeScript会报错:如果table是字符串,就不支持字符串索引操作。

解决方案

方法1:类型断言明确类型

在访问嵌套属性时,通过类型断言告诉TypeScripttable是嵌套字典类型:

fields.map((field) => (
    <strong>{(Dictionary[dictionaryRoot].table as SingleDictionaryEntry)[field] ?? field}</strong>
))

方法2:优化类型定义,固定结构

如果字典的层级结构是固定的,可以用精确的类型替代模糊的索引签名,让TypeScript能准确推断每个属性的类型:

type MenuEntry = {
    companies: string;
    clients: string;
    requests: string;
    sites: string;
};

type CompaniesTableEntry = {
    title: string;
    type: string;
    email: string;
    address: string;
    city: string;
    telephone: string;
    cellular: string;
};

type CompaniesEntry = {
    list: string;
    new: string;
    edit: string;
    delete: string;
    table: CompaniesTableEntry;
};

type Dict = {
    menu: MenuEntry;
    companies: CompaniesEntry;
};

// 实例内容保持不变
const Dictionary: Dict = {
    menu: {
        companies: 'Companies',
        clients: 'Clients',
        requests: 'Requests',
        sites: 'Sites'
    },
    companies: {
        list: 'Companies',
        new: 'Add New Company',
        edit: 'Edit',
        delete: 'Delete',
        table: {
            title: 'Title',
            type: 'Type',
            email: 'E-Mail',
            address: 'Address',
            city: 'City',
            telephone: 'Telephone',
            cellular: 'Cellular'
        }
    }
}

这种方式类型安全性最高,能在编译阶段就检测出错误的键访问。

方法3:类型守卫判断类型

如果需要保留灵活的索引签名,可以写一个类型守卫函数,在访问前判断值的类型:

function isSingleDictionaryEntry(value: string | SingleDictionaryEntry): value is SingleDictionaryEntry {
    return typeof value === 'object' && value !== null;
}

然后在组件中使用:

fields.map((field) => {
    const table = Dictionary[dictionaryRoot].table;
    const label = isSingleDictionaryEntry(table) ? table[field] : field;
    return <strong>{label ?? field}</strong>;
})

内容的提问来源于stack exchange,提问作者dkasipovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:13:23