类型防护索引属性访问-打字稿

时间:2019-04-22 07:29:32

标签: typescript

这失败了,算术运算的左侧/右侧消息应为'number','bigint'等类型。

  sort({ key, direction }: SortOptions<Listing>) {
    this.dataSet.sort((a, b) => { // <--- dataSet: Listing[]
      let returnVal;
      if (typeof a[key] === 'number' && typeof b[key] === 'number')
        returnVal = a[key] - b[key]; // <-- error here
      ...
      return direction === 'asc' ? returnVal : -returnVal;
      });
  }

键已经过类型检查为keyof T,其中a和b为T类型。

interface SortOptions<T> {
  key: keyof T;
  direction: 'asc' | 'desc';
}

export interface Listing {
  id: number;
  title: string;
  condition: string;
  description: string;
  price: number;
  stock: number;
  sold: boolean;
  display: boolean;
}

如果我删除了密钥的类型检查,即SortOptions<Listing>,则不会显示错误。但这是因为那时没有类型安全性,因为keyany,而a[key]也是any

我知道,可以使用+a[key]之类的简单javascript方法来实现此目的。但我正在尝试正确进行类型检查。

1 个答案:

答案 0 :(得分:2)

一个众所周知的问题是,TypeScript在所有情况下都不会对对象属性检查进行控制流分析。当前缺少的一些用例:property checks on index signatures with square bracketsproperty checks on values of generic types。最近已解决了一些此类情况,但是如果您在非文字键上使用索引访问,似乎仍然存在漏洞。 (不确定存在哪个现有问题)。我不确定这个特定用例是否会得到解决,因为先前的修复会降低性能。

在任何情况下,这种类型保护范围缩小对变量的作用都比对变量表达式(例如属性访问)的效果更好,因此,在有疑问时,一种合理的解决方法是将您关心的表达式分配给自己的变量: / p>

sort({ key, direction }: SortOptions<Listing>) {
    this.dataSet.sort((a, b) => { // <--- dataSet: Listing[]
        let returnVal;
        const aKey = a[key]; // assign to new variable
        const bKey = b[key]; // assign to new variable
        if (typeof aKey === 'number' && typeof bKey === 'number') // check variables
            returnVal = aKey - bKey; // no error now
        ...    
        return direction === 'asc' ? returnVal : -returnVal;
    });
}

这应该可以正常工作。希望能有所帮助;祝你好运!