0

假设我想在 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'

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

4

2 回答 2

1

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

于 2021-07-25T20:10:54.550 回答
1

Typescript 不知道这fieldName是 的属性OctDctRun,此外,它不知道data可以分配给您正在使用的属性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% 的类型安全.

这里是游乐场游乐场

于 2021-07-25T20:44:03.477 回答