我从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-of
与Object.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
关键字通常是不可取的,因为您可能会得到不属于对象的属性。