Выражения приведения типов
Выражения приведения типов позволяют расширить или подтвердить тип значения непосредственно в коде с помощью ключевого слова as.
const x = 42 as number;
В 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, вы сможете затем привести его к любому типу.
Это небезопасно и не рекомендуется. Но иногда это полезно, если вы работаете со значением, тип которого очень сложно или невозможно описать, и хотите убедиться, что результат имеет нужный тип.
Например, следующая функция клонирует объект.
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