【TS】Error: Element implicitly has an ‘any‘ type because expression of type ‘string‘ can‘t be used to

完整的报错是这样:

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';

猜你喜欢

转载自blog.csdn.net/weixin_38629529/article/details/127131932