找不到带有“字符串”类型参数的索引签名

时间:2020-05-21 07:01:04

标签: typescript

我有一个角度表,其中每行可以包含子单元格

我定义了以下接口

export interface TableCell {
  [key: string]: string | number
}

export interface TableRow {
  [key: string]: string | number | TableCell
}

我尝试建立排序功能,在其中我使用键和嵌套键来过滤此类元素

  private sort({ column, direction, subColumn }: TableSortEvent) {
    if (direction === '' || column === '') {
      return [...this.rows]
    } else {
      return [...this.rows].sort((a, b) => {
        const colA = a[column]
        const colB = b[column]
        if (
          (typeof colA === 'string' || typeof colA === 'number') &&
          (typeof colB === 'string' || typeof colB === 'number')
        ) {
          const res = this.compare(colA, colB)
          return direction === 'asc' ? res : -res
        }
        if (subColumn) {
          const subColA = colA[subColumn]
          const subColB = colB[subColumn]
          if (
            (typeof subColA === 'string' || typeof subColA === 'number') &&
            (typeof subColB === 'string' || typeof subColB === 'number')
          ) {
            const res = this.compare(subColA, subColB)
            return direction === 'asc' ? res : -res
          }
        }
        return 0
      })
    }
  }

因此,如果a[column]是字符串或数字,则将其排序,否则将检查subKey。

它工作正常,但在构建时我有以下

  No index signature with a parameter of type 'string' was found on type 'string | number | TableCell'.
      const subColB = colB[subColumn]

我该如何解决?

export interface TableSortEvent {
  column: string
  subColumn?: string
  direction: TableSortDirection
}

1 个答案:

答案 0 :(得分:1)

您的对象没有index signature,因此您不能仅使用字符串对它们进行索引,因为它不是类型安全的。

要处理此问题,可以使用keyof类型运算符,它可以说column是要排序的对象类型的有效键(而subColumn是下属对象的有效键。

没有看到更多代码,很难为您提供更新的代码,但是例如,在下面的示例中,我们通过字符串或数字属性对对象数组进行排序:

interface Foo {
    strCol: string;
    numCol: number;
}

const x: Foo[] = [
    { strCol: "1", numCol: 1 },
    { strCol: "2", numCol: 2 },
    { strCol: "3", numCol: 3 },
    { strCol: "4", numCol: 4 },
];

function sortBy(a: Foo[], col: keyof Foo) {
    a.sort((a, b) => {
        // Get the values from the objects as constants
        // Their type starts out as `string | number`.
        const avalue = a[col];
        const bvalue = b[col];
        if (typeof avalue === "string") {
            // Here, `avalue` is narrowed to `string`, and we can
            // safely assert that `bvalue` is `string` as well
            return avalue.localeCompare(bvalue as string);
        }
        // Here, `avalue` is narrowed to `number`, and we can
        // safely assert that `bvalue` is `number` as well
        return avalue - (bvalue as number);
    });
}

On the playground