Машинопись - динамически присваивать объект? - PullRequest
0 голосов
/ 26 мая 2020

Я новичок в 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 &

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Проблема в том, что TypeScript считает, что вы хотите обновить какие-либо свойства EQuiz, включая updateField. updateField требуется доступ к this, а this должен иметь тип EQuiz.

В этом случае 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;
}

Подробнее о типах this можно прочитать в Справочнике по TypeScript

1 голос
/ 26 мая 2020

Вы тестируете тип на подходе, поэтому вы можете динамично c в рамках метода без риска.

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" нужно присвоить номер. Учитывая "заблокированный" характер этой сигнатуры метода, вам необходимо решить, дает ли он вам конкретное c преимущество перед quiz.firstName = "name".

Если вы хотите, чтобы строка стала динамической c, вы немедленно теряете безопасность типов, поскольку компилятор не будет знать, является ли строка Dynami c допустимым выбором или какая из них предназначена для безопасности типов. Тогда ваша подпись может быть намного проще, и вам может потребоваться, чтобы метод проверял, действителен ли вместо этого ключ.

...