Skip to content

Latest commit

 

History

History
80 lines (57 loc) · 3.35 KB

lazyObjectLiteralInitialization.md

File metadata and controls

80 lines (57 loc) · 3.35 KB

Ленивая инициализация объекта

Довольно часто в 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`, не возможно присвоить строку числу