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

TypeScript中如何正确引用JSON结构中的变量字段名?

TypeScript中如何正确引用JSON结构中的变量字段名?

嘿,我来帮你搞定这个TypeScript的类型报错问题~首先得先指出你代码里的一个小笔误:你写的const label = ingredient1${i};会生成ingredient11、ingredient12、ingredient13这种不存在的字段名,应该改成ingredient${i}才对,不然就算解决了类型问题,也拿不到正确的食材值哦!

回到类型报错的核心问题:TypeScript之所以报错,是因为它没办法确定你动态生成的字符串label是DrinkResponseType类型里的合法键,所以默认把它当成了any类型。不用// @ts-ignore也有很多优雅的解决办法,下面给你几种常用方案:

方案一:把动态字段名断言为类型的合法键

你可以用as keyof DrinkResponseType告诉TypeScript,这个动态生成的字符串是DrinkResponseType的有效字段名,这样类型检查就会通过了:

export type DrinkResponseType = {
    id: string;
    name: string;
    ingredient1: string;
    ingredient2: string;
    ingredient3: string;
}
const drinks: Array<DrinkResponseType> = response.drinks;
drinks.forEach((item: DrinkResponseType) => {
    let all_ingredients: Array<string> = [];
    for(let i=1;i<=3;i++){
        // 修正笔误 + 类型断言
        const label = `ingredient${i}` as keyof DrinkResponseType;
        const value = item[label];
        if(value){
            all_ingredients.push(value);
        }
    }
    console.log(all_ingredients);
})  

方案二:预先定义合法的字段名数组(更推荐)

这种方式更清晰,也能避免字符串拼接带来的错误,直接遍历预先声明好的食材字段名数组:

export type DrinkResponseType = {
    id: string;
    name: string;
    ingredient1: string;
    ingredient2: string;
    ingredient3: string;
}
const drinks: Array<DrinkResponseType> = response.drinks;
// 预先定义所有食材字段的键
const ingredientKeys: Array<keyof DrinkResponseType> = ['ingredient1', 'ingredient2', 'ingredient3'];

drinks.forEach((item: DrinkResponseType) => {
    let all_ingredients: Array<string> = [];
    ingredientKeys.forEach(key => {
        const value = item[key];
        if(value){
            all_ingredients.push(value);
        }
    });
    console.log(all_ingredients);
})  

这种方案的好处是,如果以后要新增ingredient4,只需要在数组里加一个元素就行,而且TypeScript会帮你检查数组里的元素是不是合法的字段名,避免拼写错误。

方案三:给类型添加索引签名(灵活性高但不推荐)

如果你希望整个类型都支持字符串索引,可以给DrinkResponseType添加索引签名,但这样会牺牲一部分类型安全性——比如你可以用任意字符串去访问item的属性,TypeScript不会报错:

export type DrinkResponseType = {
    [key: string]: string; // 添加索引签名
    id: string;
    name: string;
    ingredient1: string;
    ingredient2: string;
    ingredient3: string;
}
// 后面的代码就可以直接用动态字符串访问了
const drinks: Array<DrinkResponseType> = response.drinks;
drinks.forEach((item: DrinkResponseType) => {
    let all_ingredients: Array<string> = [];
    for(let i=1;i<=3;i++){
        const label = `ingredient${i}`;
        const value = item[label];
        if(value){
            all_ingredients.push(value);
        }
    }
    console.log(all_ingredients);
})  

一般不推荐这种方案,除非你确实需要非常灵活的字符串索引访问,否则前面两种方案更能保持TypeScript的类型优势。

备注:内容来源于stack exchange,提问作者oderfla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:52:59