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

TypeScript报错:string无法索引DocsInfo,存在隐式any类型问题

解决TypeScript索引类型错误(TS7053)

错误信息

The element is implicitly of type "any" because an expression of type "string" cannot be used to index the type "DocsInfo".
No index signature found in type "DocsInfo" with parameter of type "string".ts(7053)

问题代码

type DocsInfo = {
    title: string;
    active?: number[];
    progress?: number[];
    closed?: number[];
};

const dict: Record<string, string> = {
        active: 'Is Active',
        progress: 'In Progress',
        closed: 'Is Closed',
};

const mappedArray = (arr: number[]) =>
    arr.map((item) => ({ key: String(item), content: item }));


const transformedArray = (data: DocsInfo) => {
        return Object.keys(data).filter((key) => key !== 'title')
            .map(key => ({
                label: dict[key], 
                options: mappedArray(data[key]) // 报错位置
            })
    )};

错误原因

Object.keys() 返回的类型是 string[],TypeScript 无法确定遍历到的 key 一定是 DocsInfo 中对应 number[] 类型的键(尽管已过滤 title),因此直接用 string 类型的 key 索引 DocsInfo 时,会触发类型不匹配错误。

解决方案

方案一:精确断言键类型并优化字典类型

通过将 Object.keys() 的结果断言为 keyof DocsInfo 类型,让 TypeScript 明确遍历的键属于 DocsInfo 的合法键;同时优化 dict 的类型,使其键与 DocsInfo 排除 title 后的键完全匹配,提升类型安全性。

type DocsInfo = {
    title: string;
    active?: number[];
    progress?: number[];
    closed?: number[];
};

// 限定dict的键为DocsInfo中排除title的键
const dict: Record<Exclude<keyof DocsInfo, 'title'>, string> = {
    active: 'Is Active',
    progress: 'In Progress',
    closed: 'Is Closed',
};

const mappedArray = (arr: number[]) =>
    arr.map((item) => ({ key: String(item), content: item }));


const transformedArray = (data: DocsInfo) => {
    return (Object.keys(data) as (keyof DocsInfo)[])
        .filter((key) => key !== 'title')
        .map(key => ({
            label: dict[key],
            // 用!断言值存在,若输入数据可能缺失键,可添加非空判断
            options: mappedArray(data[key]!)
        }));
};

方案二:为DocsInfo添加索引签名

给 DocsInfo 添加字符串索引签名,允许用任意字符串索引该类型,同时通过类型判断确保传入 mappedArray 的是数组类型:

type DocsInfo = {
    title: string;
    [key: string]: string | number[]; // 添加索引签名
    active?: number[];
    progress?: number[];
    closed?: number[];
};

const dict: Record<string, string> = {
    active: 'Is Active',
    progress: 'In Progress',
    closed: 'Is Closed',
};

const mappedArray = (arr: number[]) =>
    arr.map((item) => ({ key: String(item), content: item }));


const transformedArray = (data: DocsInfo) => {
    return Object.keys(data)
        .filter((key) => key !== 'title')
        .map(key => {
            const value = data[key];
            // 确保值是数组类型后再传入mappedArray
            if (Array.isArray(value)) {
                return {
                    label: dict[key],
                    options: mappedArray(value)
                };
            }
            return null;
        })
        .filter(Boolean); // 过滤掉可能的null项
};

方案三:使用自定义类型守卫

通过类型守卫明确键对应的 value 类型,避免类型断言:

type DocsInfo = {
    title: string;
    active?: number[];
    progress?: number[];
    closed?: number[];
};

const dict: Record<string, string> = {
    active: 'Is Active',
    progress: 'In Progress',
    closed: 'Is Closed',
};

const mappedArray = (arr: number[]) =>
    arr.map((item) => ({ key: String(item), content: item }));

// 自定义类型守卫,判断键是否对应number[]类型
function isNumberArrayKey(key: string, data: DocsInfo): key is Exclude<keyof DocsInfo, 'title'> {
    return key === 'active' || key === 'progress' || key === 'closed';
}

const transformedArray = (data: DocsInfo) => {
    return Object.keys(data)
        .filter(key => isNumberArrayKey(key, data))
        .map(key => ({
            label: dict[key],
            options: mappedArray(data[key]!)
        }));
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:32:15