Typescript Глубокое Погружение
  • Typescript Глубокое Погружение
  • Typescript проект
    • Контекст компиляции
    • Пространство декларации
    • Модули
    • Пространства имен
    • Динамический импорт выражений
  • Typescript Система типов
    • Обзор
    • Миграция с JavaScript
    • @types
    • Декларация окружения
    • Интерфейсы
    • Перечисления
    • lib.d.ts
    • Функции
    • Подлежащий выкупу
    • Тип утверждения
    • Freshness
    • Тип защиты
    • Литеральный тип
    • readonly
    • Дженерики
    • Тип вывода
    • Тип совместимости
Powered by GitBook
On this page
  • as foo и <foo>
  • Утверждения типов и преобразования типов
  • Утверждения типов считаются вредными
  • Двойное утверждение
  • Как TypeScript определяет, достаточно ли одного утверждения

Was this helpful?

  1. Typescript Система типов

Тип утверждения

TypeScript позволяет вам переопределить его выходной тип и анализировать его любым удобным для вас способом. Этот механизм называется «утверждение типа»(англ. assertion type). Утверждение типа в TypeScript используется, чтобы сообщить компилятору, что вы знаете тип лучше, чем он, и он больше не должен выдавать ошибки.

const foo = {};
foo.bar = 123; // Error: property 'bar' does not exist on `{}`
foo.bas = 'hello'; // Error: property 'bas' does not exist on `{}`

Код здесь выдает предупреждение об ошибке, потому что foo выводит тип как {}, то есть объект с нулевыми атрибутами. Следовательно, вы не можете добавить bar или bas к его свойствам, вы можете избежать этой проблемы с утверждениями типа:

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';

as foo и <foo>

Первоначальный синтаксис утверждения выглядит следующим образом:

const foo: any;
const bar = <string>foo; // bar is now of type "string"

Однако при использовании утверждений стиля <foo> в JSX существует двусмысленность в грамматике языка:

let foo = <string>bar;</string>;

Поэтому для согласованности мы рекомендуем использовать синтаксис as foo для утверждения типов.

Утверждения типов и преобразования типов

Это не называется «преобразованием типов», потому что преобразование обычно означает некоторую поддержку во время выполнения. Однако утверждение типа является чисто синтаксисом во время компиляции, и это также способ для компилятора проанализировать, как анализируется код.

Утверждения типов считаются вредными

Во многих ситуациях утверждения могут облегчить переход с устаревшего проекта (или даже вставить другой код в ваш проект из примера), однако вы должны использовать утверждения с осторожностью. Давайте использовать оригинальный код в качестве примера. Если вы не добавите свойства по соглашению, компилятор TypeScript не предупредит вас об этом:

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo;

// ahhhh .... что-то забыли?

Другая распространенная идея - использовать утверждения типа для предоставления подсказок кода:

const foo = <Foo>{
  // Компилятор предоставит подсказки кода для свойств Foo
  // Но разработчикам также может легко забыть добавить все атрибуты.
  // Точно так же, если Foo подвергается рефакторингу, этот код также может быть нарушен (например, добавлено новое свойство).
};

Это также может иметь проблему: если вы забудете свойство, компилятор не выдаст предупреждение об ошибке. Используйте лучший способ:

interface Foo {
  bar: number;
  bas: string;
}

const foo: Foo = {
  // Компилятор предоставит подсказки кода для свойства Foo
};

В некоторых сценариях вам может потребоваться создать временную переменную, но, по крайней мере, вы не будете использовать обещание (которое может быть ложным), а вместо этого будете полагаться на вывод типа для проверки вашего кода.

Двойное утверждение

Утверждения типа, хотя мы доказали, что они не настолько безопасны, все же полезны. Как показано в очень практическом примере, утверждения типа работают, как и ожидалось, когда пользователь знает более конкретный тип входящего параметра:

function handler(event: Event) {
  const mouseEvent = event as MouseEvent;
}

Однако код в следующем примере сообщит об ошибке, даже если пользователь использовал утверждения типа:

function handler(event: Event) {
  const element = event as HTMLElement; // Error: Neither 'Event' nor type 'HTMLElement' is assignable to the other
}

Если вы все еще хотите использовать этот тип, вы можете использовать двойные утверждения. Сначала утверждают, что совместимость с любым типом любого, компилятор не будет сообщать об ошибке:

function handler(event: Event) {
  const element = (event as any) as HTMLElement; // ok
}

или (если в вашем проекте запрещено any ):

function handler(event: Event) {
  const element = event as unknown as HTMLElement; // ok
}

Как TypeScript определяет, достаточно ли одного утверждения

Когда тип S является подмножеством типа T, или тип T является подмножеством типа S, S может успешно утверждаться как T. Это обеспечивает дополнительную безопасность при утверждении типа. Полностью необоснованные утверждения опасны. Если вы хотите сделать это, вы можете использовать any.

PreviousПодлежащий выкупуNextFreshness

Last updated 5 years ago

Was this helpful?