Довольно часто в JavaScript вы инициализируете объекты следующим образом:
let foo = {};
foo.bar = 123;
foo.bas = "Hello World";
Как только вы переведёте код в TypeScript, вы начнете получать следующие ошибки:
let foo = {};
foo.bar = 123; // Ошибка: свойство 'bar' не существует для типа '{}'
foo.bas = "Hello World"; // Ошибка: свойство 'bas' не существует для типа '{}'
Это потому, что из структуры let foo = {}
TypeScript логически выводит тип foo
(левая часть инициализирующего присваивания) как тип правой части {}
(т.е. объект без свойств). Поэтому произойдёт ошибка, если вы попытаетесь присвоить значение свойству, о котором компилятор не знает.
Правильный способ инициализировать объект в TypeScript - сделать это в присвоении:
let foo = {
bar: 123,
bas: "Hello World",
};
Это также отлично подходит для ревью и удобства сопровождения кода.
Паттерны быстрого решения и компромиссной ленивой инициализации, описанные ниже, страдают от забывания инициализировать свойство.
Если у вас есть большая кодовая база на JavaScript, которую вы переносите на TypeScript, идеальное решение может оказаться для вас нецелесообразным. В этом случае вы можете осторожно использовать утверждение типа, чтобы заставить компилятор замолчать:
let foo = {} as any;
foo.bar = 123;
foo.bas = "Hello World";
Конечно, использование утверждения any
может быть очень плохим решением, поскольку оно подрывает безопасность TypeScript. Компромиссное решение - создать интерфейс
, чтобы гарантировать:
- Хорошее описание
- Безопасное присвоение
Это показано ниже:
interface Foo {
bar: number
bas: string
}
let foo = {} as Foo;
foo.bar = 123;
foo.bas = "Hello World";
Вот краткий пример, показывающий, что использование интерфейса может вам помочь:
interface Foo {
bar: number
bas: string
}
let foo = {} as Foo;
foo.bar = 123;
foo.bas = "Hello World";
// позже в кодовой базе:
foo.bar = 'Hello Stranger'; // Ошибка: вы, вероятно, опечатались `bas` вместо `bar`, не возможно присвоить строку числу