Spec-Zone.ru › Flow

Выражения приведения типов

Выражения приведения типов позволяют расширить или подтвердить тип значения непосредственно в коде с помощью ключевого слова as.

const x = 42 as number;
Сравнение с TypeScript

В Flow конструкция as только расширяет тип или подтверждает его, тогда как as в TypeScript допускает небезопасное сужение типа, добавляющее несуществующие свойства. Приведение {foo: 1} as {foo: number, bar: string} проходит проверку типов в TypeScript (подтверждая несуществующий bar), но вызывает ошибку в Flow. Полное сравнение см. в разделе приведения as безопаснее в Flow.

Когда это использовать​

Используйте приведения, чтобы расширить тип значения до менее конкретного или проверить, соответствует ли значение ожидаемому типу в определённом месте кода. Чтобы сузить тип значения до более конкретного, предпочтительнее использовать уточнения типов или проверки типов — приведение через any небезопасно и должно быть крайней мерой.

Синтаксис выражений приведения типов​

Чтобы создать выражение приведения типа, используйте ключевое слово as, чтобы привести значение к типу:

value as Type

Его также можно называть «as-выражением».

Выражения приведения типов могут находиться везде, где допустимы выражения:

let val = value as Type;
let obj = {prop: value as Type};
let arr = [value as Type, value as Type] as Array<Type>;

Само значение также может быть выражением:

2 + 2 as number;

Обратите внимание, что оператор as имеет такой же приоритет, как in и instanceof. Поэтому вокруг выражения могут потребоваться скобки:

1 === 1 as boolean; // Error!
// Above same as `1 === (1 as boolean)


(1 === 1) as boolean; // Works!

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

({a: 1}) as {a: number}; // Needs parens to disambiguate from block statement
const x = {a: 1} as {a: number}; // No parens needed, as not in expression statement context

После удаления типов остаётся только значение:

value as Type;

Преобразуется в:

value;

Подтверждение типов​

С помощью выражений приведения типов можно подтвердить, что значения имеют определённые типы.

const value = 42;


value as 42;     // Works!
value as number; // Works!
value as string; // Error!

Подтверждение типов таким способом работает так же, как и в любом другом месте.

Приведение типов​

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

const value = 42;


value as 42;     // Works!
value as number; // Works!


let newValue = value as number;


newValue as 42;     // Error!
newValue as number; // Works!

Небезопасное сужение типа не допускается:

const fooObj = {foo: 1};
const otherObj = fooObj as {foo: number, bar: string};  // ERROR

Переход на синтаксис as​

Чтобы использовать ключевое слово as для приведения типов, необходимо обновить инфраструктуру, чтобы она поддерживала этот синтаксис:

  • Prettier: 3.1+
  • Babel: используйте flow-parser/babel-plugin; подробнее см. в нашем руководстве по Babel.
  • ESLint: используйте flow-eslint; подробнее см. в нашем руководстве по ESLint.

Использование выражений приведения типов​

Примечание: Мы рассмотрим упрощённый пример использования выражений приведения типов. На практике этот пример решается не лучшим образом.

Приведение типов через any​

Поскольку приведения типов работают так же, как и все остальные аннотации типов, приводить значения можно только к менее конкретным типам. Нельзя изменить тип или привести значение к более конкретному типу.

Однако с помощью any можно привести значение к любому типу.

let value = 42;


value as number; // Works!
value as string; // Error!


let newValue = value as any as string;


newValue as number; // Error!
newValue as string; // Works!

Приведя значение к any, вы сможете затем привести его к любому типу.

Это небезопасно и не рекомендуется. Но иногда это полезно, если вы работаете со значением, тип которого очень сложно или невозможно описать, и хотите убедиться, что результат имеет нужный тип.

Сравнение с TypeScript

Идиома TypeScript value as unknown as T не переносится напрямую: unknown в Flow — это настоящий верхний тип, к которому нельзя привести значение с сужением типа, поэтому для обхода ограничения в два шага нужно использовать any — value as any as T.

Например, следующая функция клонирует объект.

function cloneObject(obj: any) {
  const clone: {[string]: unknown} = {};


  Object.keys(obj).forEach(key => {
    clone[key] = obj[key];
  });


  return clone;
}

Для этого было бы трудно создать тип, поскольку мы создаём новый объект на основе другого объекта.

Если привести значение через any, можно вернуть более полезный тип.

function cloneObject<T extends {readonly [key: string]: unknown }>(obj: T): T {
  const clone: {[string]: unknown} = {};


  Object.keys(obj).forEach(key => {
    clone[key] = obj[key];
  });


  return clone as any as T;
}


const clone = cloneObject({
  foo: 1,
  bar: true,
  baz: 'three'
});


clone.foo as number;  // Works!
clone.bar as boolean; // Works!
clone.baz as string;  // Works!

См. также​

  • Уточнения типов — предпочитайте сужать типы с помощью условных проверок, а не приведения
  • Проверки типов — пользовательские функции уточнения типов как безопасная альтернатива приведению
  • Any — приведение через any для небезопасного преобразования типов (крайняя мера)
  • Подтипы — узнайте, какие приведения допустимы согласно правилам подтипов
  • Константные выражения — as const для сужения до литеральных типов и типов только для чтения
  • Обновление устаревшего синтаксиса Flow — переход от устаревших приведений с двоеточием (x: T) к синтаксису as

© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/types/casting

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API