Typescript - 动态对象分配?

Typescript - Dynamically object assign?

老实说,我对 Typescript 和 JS 之外的任何东西都很陌生。

我想按照

创建一个类似于 JS 函数的函数
updateField(key, val) {
    this[key] = val
  }

我不知道这在打字稿中是否可以实现。如果这是不应该做的事情并且打破了打字稿的重点,我想我很乐意创建多个功能。

我曾尝试按照类似问题的其他答案进行操作,但遇到了瓶颈,不确定还能尝试什么.. 但这就是我结束的地方。注意:我正在使用 mobx,因此使用 'this'

甚至对为什么无法实现这一目标进行更好的教育感到高兴。

export class WhoForSelection {
  @persist @observable label = ''
  @persist @observable value = ''
}

class EQuiz {
  whoFor: WhoForSelection

  fistName: string
  dob: string
  gender: string

  @action
  updateField<T extends keyof EQuiz, K extends EQuiz[T]>(name: T, value: K) {
    this[name] = value
  }
}

有错误

(parameter) name: T extends "whoFor" | "fistName" | "dob" | "gender" | "updateField"
Type 'K' is not assignable to type 'this[T]'.
  Type 'EQuiz[T]' is not assignable to type 'this[T]'.
    Type 'EQuiz' is not assignable to type 'this'.
      'EQuiz' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'EQuiz'.
        Type 'EQuiz[T]' is not assignable to type 'WhoForSelection &

您正在测试中的类型,因此您可以在方法内进行动态操作而没有风险。

class EQuiz {
  firstName: string = '';
  dob: string = '';
  gender: string = '';
  test: number = 0;

  updateField<T extends keyof EQuiz, K extends EQuiz[T]>(name: T, value: K) {
    this[name] = value as any;
  }
}

const quiz = new EQuiz();

quiz.updateField("firstName", "name");
quiz.updateField("test", 1);

自动完成告诉你 "firstName" 需要给定一个字符串,"test" 需要给定一个数字。鉴于此方法签名的 "locked down" 性质,您需要确定它是否为您提供了优于 quiz.firstName = "name".

的特定优势

如果您的意图是让字符串变成动态的,您会立即失去类型安全,因为编译器不知道动态字符串是否是一个有效的选择,或者它是为了类型安全而选择的。那么您的签名可能会简单得多,您可能需要让方法检查密钥是否有效。

问题是 TypeScript 认为您想更新 EQuiz 的任何属性,包括 updateFieldupdateField 需要访问 this 并且它要求 thisEQuiz.

类型

在这种情况下,TypeScript 要求您明确说明 updateField 需要特定的 this:

// Notice the "this" as the first argument
updateField<T extends keyof EQuiz, K extends EQuiz[T]>(this: EQuiz, name: T, value: K) {
  this[name] = value;
}

您可以在 TypeScript handbook

中阅读有关 this 类型的更多信息