元素隐式具有"any"类型,因为索引表达式不是"数字"类型 [7015]



我从David Walsh的css动画回调中获取了代码,并将其修改为TypeScript。然而,我得到了一个错误,我不知道为什么:

interface IBrowserPrefix {
[key: string]: string;
}
// http://davidwalsh.name/css-animation-callback
function whichAnimationEvent() {
let x: keyof IBrowserPrefix;
const el = document.createElement('temp');
const browserPrefix: IBrowserPrefix = {
animation: 'animationend',
OAnimation: 'oAnimationEnd',
MozAnimation: 'animationend',
WebkitAnimation: 'webkitAnimationEnd',
};
for (x in browserPrefix) {
if (el.style[x] !== undefined) {
//           ^---- [TS Error]: Element has 'any' type b/c index expression is not of type 'number'
return browserPrefix[x];
}
}
}

之所以会发生这种情况,是因为您试图使用带字符串键的数字索引签名对对象进行索引。

for x in browserPrefix将返回一组键,这些键是字符串。但是,由于某些原因,CSSStyleDeclaration的索引类型设置为number(而不是string(-请参阅https://github.com/Microsoft/TypeScript/issues/17827.

您之所以出现此错误,是因为您已打开--noImplicitAny。实现此操作的一种方法(一种巧妙的方法(是将索引器强制转换为字符串:

for (x in browserPrefix) {
if (el.style[x as any] !== undefined) {
return browserPrefix[x];
}
}

另一种方法是修改打字法(试着在github上解决这个问题(。

当我们在这里的时候,你应该用const标记x,如果你要在对象上使用for,你应该确保该属性属于该对象,以避免引入原型链中继承的任何东西:

for (const x in browserPrefix) {
if (browserPrefix.hasOwnProperty(x) && el.style[x as any] !== undefined) {
return browserPrefix[x];
}
}

或者,将for-ofObject.keys一起使用,而不是使用for-in

这里没有必要提前定义x

代码中有几个问题,第一个问题是IBrowserPrefix被定义为具有字符串索引,因此keyof IBrowserPrefix;实际上是字符串。我会删除接口,只使用let x: keyof typeof browserPrefix;

下一个问题是typescript定义CSSStyleDeclaration接口的方式。它只包括标准属性,而不包括特定于供应商的属性。

您可以使用类型断言来告诉编译器您知道自己在做什么,并忽略错误

export function whichAnimationEvent() {
const el = document.createElement('temp');
const browserPrefix = {
animation: 'animationend',
OAnimation: 'oAnimationEnd',
MozAnimation: 'animationend',
WebkitAnimation: 'webkitAnimationEnd',
};
let x: keyof typeof browserPrefix;
for (x in browserPrefix) {
if (el.style[x as keyof CSSStyleDeclaration] !== undefined) {
return browserPrefix[x];
}
}
}

您还可以使用所需的特定于供应商的密钥使用CSSStyleDeclaration进行扩展。

尝试for (x of Object.keys(browserPrefix))而不是for (x in browserPrefix)

在循环中使用in关键字通常是不可取的,因为您可能会得到不属于对象的属性。

最新更新