Почему я могу обойти ограничение литералов объекта TypeScript с помощью временной переменной? - PullRequest
0 голосов
/ 20 апреля 2020

Простой пример кода:

type Foo = { foo: string };
type FooBar = { foo: string; bar: number };

let a: Foo;

// Doesn't work
a = { foo: 'x', bar: 1 };
/*
 Type '{ foo: string; bar: number; }' is not assignable to type 'Foo'.
  Object literal may only specify known properties, and 'bar' does not exist in type 'Foo'.
*/

// However this works: (temp variable with implicit type)
let b = { foo: 'x', bar: 1 }; // According to VSCode the inferred type for `b` is exactly `{ foo: string; bar: number; }`
a = b;

// This also works: (temp variable with explicit type)
let c: FooBar = { foo: 'x', bar: 1 };
a = c;

Это меня очень удивляет. То, что я ожидал, является ошибкой во всех трех случаях. Мне очень нравится идея « Object литерал может указывать только известные свойства ».

# 1 Почему это происходит?

# 2 Как я могу настроить TypeScript, чтобы не допустить этого «обходного пути»?

1 Ответ

1 голос
/ 20 апреля 2020

Это не обходной путь, но как совместимость типов определена в машинописи:

Основное правило c для структурной системы типов TypeScript состоит в том, что x совместим с y, если у y есть как минимум те же члены, что и у x


Теперь, почему ошибки первого примера (let a: Foo = { foo: 'x', bar: 1 })? Это называется проверка избыточных свойств :

Литералы объектов получают специальную обработку и при проверке go избыточные свойства при назначении их другим переменным или передаче их в качестве аргументов. Если у литерала объекта есть какие-либо свойства, которых нет у «целевого типа», вы получите ошибку


Как я могу настроить TypeScript, чтобы не допустить этого «обходного пути»? Это невозможно в настоящее время. Вы можете найти старое обсуждение точных типов здесь , но я сомневаюсь, что это приведет к машинописи в ближайшем будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...