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

如何为使用Object.keys()的嵌套对象函数添加类型定义?

解决TypeScript嵌套对象遍历的类型定义问题

你的问题根源在于Object.keys()默认返回string[]类型,而非对象键的字面量类型(比如keyof InitialStateTypes),TypeScript无法推断item和el是对应对象的合法键,导致访问filteringState[item][el]和filteringData[item]时出现类型错误。下面是两种可行的解决方式:

方式一:用类型断言修正Object.keys()返回类型

直接给Object.keys()的结果添加类型断言,让TypeScript识别出键的具体类型:

interface InitialStateTypes {
    country: {
        "italy": boolean,
    },
    board: {
        "full": boolean,
    },
    transport: {
        "bus": boolean,
        "own": boolean
    },
}

interface FilteringDataTypes {
    country: string[],
    board: string[],
    transport: string[],
}

const collectFilteringData = (filteringState: InitialStateTypes) => {
    // 直接初始化空数组,避免类型断言
    const filteringData: FilteringDataTypes = {
        country: [],
        board: [],
        transport: []
    };

    // 断言Object.keys返回InitialStateTypes的键数组
    (Object.keys(filteringState) as Array<keyof InitialStateTypes>).forEach((item) => {
        const nestedObj = filteringState[item];
        // 断言嵌套对象的键数组类型
        (Object.keys(nestedObj) as Array<keyof typeof nestedObj>).forEach((el) => {
            if (nestedObj[el]) {
                filteringData[item].push(el);
            }
        });
    });
    return filteringData;
};

export default collectFilteringData;

方式二:封装泛型函数获取类型安全的对象键

如果需要多次使用类型安全的键遍历,可以封装一个泛型函数替代原生Object.keys():

interface InitialStateTypes {
    country: {
        "italy": boolean,
    },
    board: {
        "full": boolean,
    },
    transport: {
        "bus": boolean,
        "own": boolean
    },
}

interface FilteringDataTypes {
    country: string[],
    board: string[],
    transport: string[],
}

// 泛型函数,返回对象键的字面量类型数组
function getObjectKeys<T extends object>(obj: T): Array<keyof T> {
    return Object.keys(obj) as Array<keyof T>;
}

const collectFilteringData = (filteringState: InitialStateTypes) => {
    const filteringData: FilteringDataTypes = {
        country: [],
        board: [],
        transport: []
    };

    getObjectKeys(filteringState).forEach((item) => {
        const nestedObj = filteringState[item];
        getObjectKeys(nestedObj).forEach((el) => {
            if (nestedObj[el]) {
                filteringData[item].push(el);
            }
        });
    });
    return filteringData;
};

export default collectFilteringData;

两种方式都能解决类型推断问题,同时保持代码的类型安全。方式二更适合多场景复用,方式一则更直接简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:20:32