元素隐式具有“任何”类型,因为索引表达式不是“数字”类型[7015]

问题描述 投票:1回答:3

我从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];
    }
  }
}
javascript typescript
3个回答
0
投票

发生这种情况是因为您尝试使用带有字符串键的数字索引签名来索引对象。

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-ofObject.keys而不是for-in

没有必要提前定义x


1
投票

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

通常不赞成使用in关键字作为循环,因为you may get properties that do not belong to the object


0
投票

代码中有几个问题,第一个问题是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扩展您需要的供应商特定密钥。

© www.soinside.com 2019 - 2024. All rights reserved.