我从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
。让这个工作(一种hacky方式)的方法是将索引器转换为字符串:
for (x in browserPrefix) {
if (el.style[x as any] !== undefined) {
return browserPrefix[x];
}
}
另一种方法是修改类型(尝试在github上碰撞问题)。
当我们在这里时,你应该用x
标记const
,如果你要在一个对象上使用for-in,你应该确保该属性属于该对象,以避免拉入原型链中继承的任何东西:
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
。
试试for (x of Object.keys(browserPrefix))
而不是for (x in browserPrefix)
。
通常不赞成使用in
关键字作为循环,因为you may get properties that do not belong to the object。
代码中有几个问题,第一个问题是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
扩展您需要的供应商特定密钥。