Система типов TypeScript неверна в некоторых местах;Вы нашли эту проблему , в которой псевдонимы типов , но не интерфейсы , получают подписи неявного индекса . Предоставление типа неявной подписи индекса полезно, но в целом небезопасно. Обратите внимание:
const fooBar = { foo: "foo", bar: 123 };
const tFooBar: T = fooBar; // okay
const uFooBar: U = tFooBar; // okay?
const whoopsie = uFooBar.bar; // string at compile time, number at runtime?!
console.log(whoopsie);
Значение fooBar
является допустимым T
, поскольку оно имеет свойство foo
типа string
. Таким образом, вы можете назначить его на tFooBar
. И затем, так как TypeScript позволяет вам присвоить значение типа T
переменной типа U
, вы можете присвоить tFooBar
uFooBar
. И теперь необоснованность разоблачена, если вы прочитаете свойство bar
uFooBar
. Это должно быть string
в соответствии с U
, но это number
. Упс.
Неявные подписи индекса полезны, потому что часто функции требуют значений с подписью индекса, и это полезно для значений, чьи известные свойства соответствуют подписи индекса, чтобы быть принятыми. Итак, у нас есть эта полезная вещь, которая может привести к небезопасному поведению. Что должно быть сделано?
По-видимому, текущее правило для TypeScript:
- объектным литералам / анонимным типам присваиваются неявные индексные сигнатуры
- псевдонимам типов присваивается неявный индексподписи
- интерфейсам НЕ даны неявные индексные подписи
Очевидно, что последнее является преднамеренным и не является ошибкой, согласно этому комментарию @ RyanCavanaugh :
Просто чтобы заполнить людей, это поведение в настоящее время разработано. Поскольку интерфейсы могут быть дополнены дополнительными объявлениями, а псевдонимы типов не могут, «безопаснее» (тяжелые кавычки на этом) выводить неявную сигнатуру индекса для псевдонимов типов, чем для интерфейсов. Но мы рассмотрим это и для интерфейсов, если это кажется целесообразным.
Таким образом, мысль о том, что объединение объявлений может нарушить совместимость интерфейса с индексом-подписью, но псевдонимы типов не могут. Возможно, они готовы его изменить, и если у вас есть убедительный вариант использования, вы можете обратиться к проблеме Github и упомянуть об этом.
Хорошо, надеюсь, это поможет;удачи!
Ссылка на код