【问题标题】:Element implicitly has an 'any' type because index expression is not of type 'number' [7015]元素隐式具有“任何”类型,因为索引表达式不是“数字”类型 [7015]
【发布时间】:2023-04-01 06:49:01
【问题描述】:

我从 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


    【解决方案1】:

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

    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 上提出问题)。

    当我们在这里时,你应该用const 标记x,如果你要在一个对象上使用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

    【讨论】:

    • el.style 是一个对象,而不是一个数组。例如,document.body.style.color。 OP 将其引用为document.body.style['color'],这是有效的。
    • @CharlesStover 是的,是的。但是,TypeScript 类型的索引设置为数字,而不是字符串 - 因此问题。我忘了从我的帖子中删除数组评论,谢谢指出
    • 在 for-of 中出现此错误
    • 你能重现codesandbox.io中的错误吗,@BenRacicot?
    【解决方案2】:

    代码中有几个问题,第一个是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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-08-01
        • 2023-02-15
        • 2022-06-12
        • 2022-01-22
        • 2018-04-25
        • 2021-10-11
        • 2017-03-14
        • 2016-07-23
        • 1970-01-01
        相关资源
        最近更新 更多