完整的报错是这样:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type
该报错一般出现在使用对象获取值的场景。
const obj = {
name: '张三',
age: 20,
};
const str = 'name' as string;
/**
Error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ name: string; age: number; }'.
No index signature with a parameter of type 'string' was found on type '{ name: string; age: number; }'.ts
*/
obj[str];
我们只需要确保str是obj的key就可以避免报错,常用的方式有以下几种:
方法一:
interface Person {
name: string,
age: number,
}
const obj: Person = {
name: '张三',
age: 20,
};
const str = 'name' as string;
console.log(obj[str as keyof typeof obj]);
方法二:
interface Person {
name: string,
age: number,
}
const obj: Person = {
name: '张三',
age: 20,
};
const str = 'name' as string;
console.log(obj[str as keyof Person]);
可以看到,这两种方式,极其相似,这里为什么不用typeof,是因为Person是我们定义的类型,而不是对象,两种方式得到的结果都是一样的。
// type T = 'name' | 'age'
type T = keyof Person;
type T = keyof typeof obj;
当然,如果str没有使用类型断言,这么写也是没有问题的,如下:
interface Person {
name: string,
age: number,
}
const obj: Person = {
name: '张三',
age: 20,
};
const str = 'name';
console.log(obj[str]);
好了,我们再考虑另一种场景,如果我obj对象里的属性很多,我很多地方都会用到obj对象里的key,总不能一个个都是keyof或者keyof typeof一下吧,有没有更好一点的方案呢?
方式三:
interface Person {
name: string,
age: number,
}
const obj: Person = {
name: '张三',
age: 20,
};
const str: keyof Person = 'name';
console.log(obj[str]);
如果我想给obj新增一个属性呢?直接加肯定会报错,如下:
interface Person {
name: string,
age: number,
}
const obj: Person = {
name: '张三',
age: 20,
};
// Error: Property 'sex' does not exist on type 'Person'.ts
obj.sex = 'boy';
在不确定key的值是否存在obj对象里时,可以使用下面这种方式:
interface Person {
name: string,
age: number,
[key: string]: any,
}
const obj: Person = {
name: '张三',
age: 20,
};
obj.sex = 'boy';