由于索引错误,Typescript 中的方法无法编译

Method in Typescript does not compile because of Index Error

假设我想在 Typescript 中定义这个方法:

setResult(guId: string,fieldname: string, data:Array<UsedTsoClusterKey>) {
  let octdctruns: OctDctRun[] = [...this.octDctRuns];
  const index = octdctruns.findIndex((o) => o.guid === guId);
  octdctruns[index][fieldname] = data;
  this.octDctRuns = octdctruns;
}

UsedTsoClusterKey 和 OctDctRun 如下所示:

export interface UsedTsoClusterKey {
  runGUID: string;
  tsoClusterKeyID: string;
  tsoClusterKeyVersion: string;
  validFrom: DateString;
  validUntil: DateString;
}

export interface OctDctRun {
  guid: string;
  moduleType: string;
  runTime: DateString;
  calcIntervalFrom: DateString;
  calcIntervalUntil: DateString;
  triggerType: string;
  triggerID: string;
  usedTSOClusterKeys: UsedTsoClusterKey[];
}

但是我在行 octdctruns[index][fieldname] = data:

中收到错误
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'OctDctRun'.
  No index signature with a parameter of type 'string' was found on type 'OctDctRun'

我不明白这里的问题。请帮忙!

fieldname: keyof OctDctRun - 这将解决您当前的问题,但这是另一个问题:data 是一个 UsedTsoClusterKey 实体数组,因此它只能分配给 usedTSOClusterKeys 根据你的类型定义。所以正确的类型定义是这样的:keyof Pick<OctDctRun, 'usedTSOClusterKeys'>,但我不确定它是否涵盖你的情况¯_(ツ)_/¯

Typescript 不知道 fieldNameOctDctRun 的 属性,此外,它不知道 data 可分配给 [=28] =] 您正在使用 fieldName 寻址。提供的另一个答案确实为此提供了解决方案,尽管有点特定于您的用例。但是,有一种更动态的方法可以做到这一点,不需要硬编码 data:

的类型
class Test {
    setResult<FieldName extends keyof OctDctRun>(guId: string, fieldName: FieldName, data: OctDctRun[FieldName]) {
        let octdctruns = [...this.octDctRuns];
        const index = octdctruns.findIndex((o) => o.guid === guId);
        octdctruns[index][fieldName] = data;
        this.octDctRuns = octdctruns;
    }
}

如果你使用泛型 FieldName 必须是 OctDctRun 的键,然后说参数 fieldName 必须是那种类型,然后说 data 必须是一个可分配给 fieldName 的值,您在 100% 的时间里获得 100% 的类型安全。

这里是游乐场Playground