Кортежи — это более легкая альтернатива объектам, когда вы хотите сгруппировать данные, поскольку для различения элементов используются позиции, а не имена свойств. Однако до сих пор кортежным типам не хватало многих полезных функций, предоставляемых объектными типами!
- Маркированные элементы кортежа:
type T = [foo: number, bar: string]
- Аннотации отклонений (только для чтения/только для записи) для элементов кортежа:
type T = [+foo: number, -bar: string]
- Необязательные элементы кортежа:
type T = [foo?: number, bar?: string]
- Распространение кортежа
type T = [number, string, ...OtherTuple]
- Уточнение длины кортежа
Прочтите полную документацию.
Маркированные элементы кортежа
Теперь вы можете добавить метку к элементам кортежа. Метки не влияют на тип элемента кортежа, но полезны для самостоятельного документирования назначения элементов кортежа, особенно когда несколько элементов имеют один и тот же тип.
type Range = [x: number, y: number];
Метки также необходимы для добавления к элементам аннотаций отклонений или модификаторов необязательности.
Аннотации отклонений для элементов кортежа и кортежей, доступных только для чтения.
Вы можете добавлять аннотации дисперсия (для обозначения только для чтения/только для записи) к помеченным элементам кортежа, как и к свойствам объекта:
type T = [+foo: number, -bar: string];
Это позволяет помечать элементы как доступные только для чтения или только для записи. Например:
function f(readOnlyTuple: [+foo: number, +bar: string]) { const n: number = readOnlyTuple[0]; // OK to read readOnlyTuple[1] = 1; // ERROR! Cannot write }
Вы также можете использовать $ReadOnly
для типов кортежей как сокращение для обозначения каждого свойства как доступного только для чтения:
type T = $ReadOnly<[number, string]>; // Same as `[+a: number, +b: string]`
Необязательные элементы кортежа
Вы можете пометить элементы кортежа как необязательные с помощью ?
после метки элемента. Это позволяет опустить необязательные элементы. Необязательные элементы должны находиться в конце типа кортежа после всех обязательных элементов.
type T = [foo: number, bar?: string]; ([1, "s"]: T); // OK: has all elements ([1]: T); // OK: skipping optional element
Вы не можете записать undefined
в необязательный элемент — добавьте | void
к типу элемента, если хотите:
type T = [foo?: number, bar?: number | void]; declare const x: T; x[0] = undefined; // ERROR ([undefined]: T); // ERROR x[1] = undefined; // OK: we've added `| void` to the element type
Вы также можете использовать типы утилит Partial
и Required
, чтобы сделать все элементы необязательными или обязательными соответственно:
type AllRequired = [number, string]; ([]: Partial<AllRequired>); // OK: like `[a?: number, b?: string]` now type AllOptional = [a?: number, b?: string]; ([]: Required<AllOptional>); // ERROR: like `[a: number, b: string]` now
Кортежи с необязательными элементами имеют арность (длину), которая представляет собой диапазон, а не одно число. Например, [number, b?: string]
имеет длину 1–2.
Распространение типа кортежа
Вы можете разделить тип кортежа на другой тип кортежа, чтобы создать более длинный тип кортежа:
type A = [number, string]; type T = [...A, boolean]; // Same as `[number, string, boolean]` ([1, "s", true]: T); // OK
Спреды кортежей сохраняют дисперсию и опциональность. Вы не можете разбивать массивы на кортежи, только на другие кортежи.
Уточнение по длине
Вы можете уточнить объединение кортежей по их длине:
type Union = [number, string] | [boolean]; function f(x: Union) { if (x.length === 2) { // `x` is `[number, string]` const n: number = x[0]; // OK const s: string = x[1]; // OK } else { // `x` is `[boolean]` const b: boolean = x[0]; } }
Технически это не новая функция, о которой ранее не сообщалось.
Принятие
Чтобы использовать помеченные элементы кортежа (включая необязательные элементы и аннотации отклонений к элементам) и элементы расширения кортежа, вам необходимо обновить свою инфраструктуру, чтобы она поддерживала синтаксис:
flow
иflow-parser
: 0,212,0prettier
: 3babel
сbabel-plugin-syntax-hermes-parser
. Инструкции по настройке см. в нашем руководстве по Babel.eslint
сhermes-eslint
. Инструкции по настройке см. в нашем руководстве по ESLint.
Бонус: declare const
и declare let
Flow теперь поддерживает declare const
и declare let
(в дополнение к существующему declare var
). Они позволяют вам объявить переменную с типом, но без реализации. Они полезны для написания определений библиотек или создания воспроизведений проблем в Try Flow при использовании современных const
и let
вместо устаревших var
. И declare const
, и declare let
являются блочными, как и их эквиваленты, отличные от declare
.
if (cond) { declare const foo: number; } foo; // ERROR: cannot resolve `foo` (as it's block-scoped)