元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型 类型“Object”上不存在属性xxx 类型 “xxx“ 到类型 “xxx“ 的转换可能是错误

全部报错

  1. 元素隐式具有 “any” 类型,因为类型为 “string” 的表达式不能用于索引类型

  2. 类型“Object”上不存在属性xxx

  3. 类型 “xxx” 到类型 “xxx” 的转换可能是错误的,因为两种类型不能充分重叠。如果这是有意的,请先将表达式转换为 “unknown”

数据结构

  const data = {
    "spleen": {
        organ: '脾脏',
        organ_Eng: 'spleen',
        x: {
            diameter: [2, 3, 4],
            area: [1, 2, 3]
        },
        y: {
            diameter: [2, 3, 4],
            area: [1, 2, 3]
        },
        z: {
            diameter: [2, 3, 4],
            area: [1, 2, 3]
        }
    },
    "rightKidney": {
        organ: '右肾',
        organ_Eng: 'rightKidney',
        x: {
            diameter: [2, 3, 4],
            area: [1, 2, 3]
        },
        y: {
            diameter: [2, 3, 4],
            area: [1, 2, 3]
        },
        z: {
            diameter: [2, 3, 4],
            area: [1, 2, 3]
        }
    },
  }

目的

我想要访问这个对象最里层的结构,除了diameter以及area之外,其他的都需要通过变量去访问
现有变量如下:

const config = {
        organ: 'spleen',
        axis: 'x',
        slice: 3,
    }

我想要用类似于以下的这种方式来进行访问

const organData = data[config.organ]; // 当前器官
const axisData = organData[config.axis] // 当前坐标轴
const slice = config.slice // 当前切片

第一个报错

报错了,报错长这个样子:

元素隐式具有 “any” 类型,因为类型为 “string” 的表达式不能用于索引类型
找不到具有类型为 “string” 的参数的索引签名

对于这个问题,第一个解决方法是给对象加一个类型的声明,代码是这样的:

interface dataObj {
    [organ: string]: any
};

  const data = {
    "spleen": {
		// ...
    },
    "rightKidney": {
    	// ...
    },
  } as dataObj 

为什么要写any呢?写any的话ts的作用不就没有了吗?那就不写any吧,从Object开始进行尝试,像以下这样使用的时候报错了

const options = Object.values(data).map((value)=>{
    return {value: value.organ_Eng, label: value.organ}
});

第二个报错

报错了,报错长这个样子

类型“Object”上不存在属性“organ_Eng”

分析一下这个报错,它的意思就是我得把整个对象里面各种元素的类型给写出来,写就写呗,然后我就把类型定义弄成这样了

type axisObj = {
    diameter: number[],
    area: number[],
}

interface dataObj {
    [organ: string]: {
        organ: string,
        organ_Eng: string,
        x: axisObj,
        y: axisObj,
        z: axisObj,
    }
};

然后在以下的代码中出现了新的报错:

const axisData = organData[axis]

报错:
元素隐式具有 “any” 类型,因为类型为 “string” 的表达式不能用于索引类型
在类型 上找不到具有类型为 “string” 的参数的索引签名。

好像又回到了起点。。。,分析一下,大概就是跟一开始的报错是一个意思,没有声明不能随便用,那行呗,加个声明。
然后我又在以上的代码的基础上将代码修改成这样:

interface organObj {
    [axis: string]: axisObj,
}

const organData = data[config.organ] as organObj; // 当前器官

第三个报错

新的报错出现了,长这个样子:

类型 “{ organ: string; organ_Eng: string; x: axisObj; y: axisObj; z: axisObj; }” 到类型 “organObj” 的转换可能是错误的,因为两种类型不能充分重叠。如果这是有意的,请先将表达式转换为 “unknown”。
属性“organ”与索引签名不兼容。
类型“string”不可与类型“axisObj”进行比较

既然让我们加unknown,那就加上试一试,代码变成这样了:

const organData = data[config.organ] as unknown as organObj; // 当前器官

报错没有了,皆大欢喜。

总结

所以有以下的两种解决方法,详细的代码我都放出来:

相同的部分

  const data = {
    "spleen": {
		// ...
    },
    "rightKidney": {
		// ...
    },
  }  as dataObj

const config = {
        organ: 'spleen',
        axis: 'x',
        slice: 3,
    }

第一种解决方案

interface dataObj {
    [organ: string]: any
};

const organData = data[config.organ]; // 当前器官
const axisData = organData[config.axis] // 当前坐标轴
const slice = config.slice // 当前切片

第二种解决方案

type axisObj = {
    diameter: number[],
    area: number[],
}

interface organObj {
    [axis: string]: axisObj,
}

interface dataObj {
    [organ: string]: {
        organ: string,
        organ_Eng: string,
        x: axisObj,
        y: axisObj,
        z: axisObj,
    }
};

const organData = data[config.organ] as unknown as organObj; // 当前器官
const axisData = organData[config.axis] // 当前坐标轴
const slice = config.slice // 当前切片
### 回答1: 元素具有 "any" 类型,是因为在 TypeScript 中,如果一个对象没有明确指定类型,那么它的类型就是 "any"。在这种情况下,如果我们尝试使用一个类型为 "string" 的表达式索引这个对象,TypeScript 就会报错,因为 "string" 类型不能用于索引类型。因此,为了避免这种错误,我们需要明确指定对象的类型,或者使用类型断言来告诉 TypeScript 我们知道这个对象的类型是什么。 ### 回答2: 在 TypeScript 中,元素具有 "any" 类型,原因是因为如果我们声明数组时没有指定数组内元素类型TypeScript 就无法确定数组内元素类型。 例如,如果我们声明了一个空数组变量 arr,但是并没有在声明时指定 arr 变量的类型,那么 TypeScript知道这个数组的元素类型是什么。 在使用元素时,如果我们尝试使用类型为 "string" 的表达式来做数组索引,就会出现问题,因为这样的表达式不能用作索引类型。 因此,为了避免这种情况,TypeScript 就将元素指定为 "any" 类型,这样在使用元素时,就可以使用任何类型表达式来做索引,从而避免了出现类型错误的情况。 需要注意的是,虽然 TypeScript元素指定为 "any" 类型,但是我们可以在声明数组时,显指定数组内元素类型,这样就可以让 TypeScript 知道数组内元素的具体类型,从而更好地检查代码的类型安全性。 ### 回答3: 在 TypeScript 中,元素类型默认是 "any" 类型。这意味着我们可以将任何类型的值添加到数组或对象中,而需要对其类型进行任何限制。而索引类型是一种特殊的类型,在 TypeScript 中,它可以用于对象或数组的索引访问,例如 obj[key] 或者 arr[index]。 如果我们尝试对一个 "string" 类型表达式进行索引访问,就会出现类型错误。因为 "string" 类型表达式不能用于索引类型,因此 TypeScript 编译器无法确定我们要访问对象或数组中的哪个元素,这也就导致了类型错误。 因此,元素类型应该被指定为 "any" 类型,这样就可以将任何类型的值添加到数组或对象中,而会出现类型错误。但是,在实际开发中,为了让代码更加可读和维护,我们应该尽量指定元素的具体类型,这能够减少代码错误,并且在之后的开发过程中能够更容易地维护和修改代码。 总结:元素具有 "any" 类型,因为类型为 "string" 的表达式不能用于索引类型。在实际开发中,应该尽量指定元素的具体类型,以提高代码可读性、减少代码错误和更容易地维护和修改代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值