user_of_toster
@user_of_toster

Почему компилятор выдает ошибку?

type MyType1 = {
  [key:string]: string
}

class One {
  constructor({obj}: {obj: MyType1 | undefined}) {}

}

interface myType {
  a?: string
  b?: string
}

class Two extends One {
  constructor(obj: undefined | myType) {
    super({obj}) //Type 'myType' is not assignable to type 'MyType1'. Index signature is missing in type 'myType'.
  }
}

One принимает объект с широкой областью свойств, а Two сужает свойства до двух.

Не понятна логика, почему компилятор ругается. Ведь подкласс сужает аргументы суперкласса, а не наоборот. И почему компилятор перестает ругаться, если заменить интерфейс myType на тип?
  • Вопрос задан
  • 60 просмотров
Решения вопроса 1
@Sun_Day
[key:string]: string

Не тоже самое, что:

a?: string

One принимает объект с широкой областью свойств, а Two сужает свойства до двух.


В данном случае типобезопасность по другому работает. В команде тайпскрипт решили, что в type для объекта безопасно неявно выводить index signature(то самое [key:string]), но не для интерфейсов, т.к интерфейсы можно расширять дополнительными объявлениями, а type нет. По сути это как-то немного странно и я так и не понял до конца, чем оно мотивировано и не нашел никаких конкретных кейсов пользы такого разделения(возможно для какого-то очень абстрактного кейса, когда может случится конфуз с обращением к несуществующему ключу объекта и ts это пропустит).

Еще с ts 2.2.2 висит в issues

Можно просто сделать вот так
interface myType extends MyType1

Ну либо поменять на type вместо interface. Так бы я и сделал.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы