Типы литералов
Типы литералов ограничивают значение конкретным примитивом — определённой строкой, числом, логическим значением или bigint.
function acceptsTwo(value: 2) { /* ... */ }
acceptsTwo(2); // Works!
acceptsTwo(3); // Error! Типы литералов поддерживают логические значения (true, false), числа (42, 3.14), строки ("foo") и bigint (42n). Их часто используют в сочетании с объединениями типов:
function getColor(name: "success" | "warning" | "danger") {
switch (name) {
case "success" : return "green";
case "warning" : return "yellow";
case "danger" : return "red";
}
}
getColor("success"); // Works!
getColor("danger"); // Works!
getColor("error"); // Error! Когда это использовать
Используйте типы литералов, когда нужно ограничить значение определёнными константами, а не более широким типом, например string или number. Они особенно полезны в объединениях для определения фиксированного набора допустимых значений (например, "success" | "error"). Если нужно сохранить узкий тип литерального значения внутри объекта или массива — где типы свойств по умолчанию расширяются, — используйте as const; см. раздел Расширение типов литералов ниже. В качестве более структурированной альтернативы объединениям литералов рассмотрите перечисления Flow.
Расширение типов литералов
Привязка const сохраняет узкий тип примитивного литерала; привязка let расширяет его до базового примитивного типа, поскольку let допускает переназначение, и более узкий тип перестал бы быть корректным:
const c = "success"; c as "success"; // Works! — c has the literal type "success" let l = "success"; l as "success"; // Error — l has been widened to string
Литералы объектов и массивов расширяются ещё сильнее: тип каждого свойства расширяется до базового примитивного типа, а литералы массивов расширяются от кортежа до Array<base> — даже если окружающая привязка имеет тип const, поскольку содержимое всё ещё можно изменять. Используйте as const, чтобы сохранить типы литералов, структуру кортежа и запретить изменение содержимого:
const o = {x: 1}; // type is {x: number}
const oConst = {x: 1} as const; // type is {readonly x: 1}
oConst.x as 1; // Works!
o.x as 1; // Error — o.x is number
const arr = ["a", "b"]; // type is Array<string>
const tuple = ["a", "b"] as const; // type is Readonly<["a", "b"]>
tuple[0] as "a"; // Works!
arr[0] as "a"; // Error — arr[0] is string
tuple as ReadonlyArray<"a" | "b">; // Works — Readonly<["a", "b"]> is a subtype Поскольку as const создаёт свойства только для чтения, значение, созданное с помощью as const, нельзя передать параметру, свойство которого доступно для записи (свойства объектов по умолчанию инвариантны). Чтобы принять такое значение, пометьте принимающий параметр как readonly:
const e = {kind: "click"} as const;
function setKind(o: {kind: "click"}) {}
setKind(e); // Error — `kind` is read-only on `e` but writable on the parameter
function readKind(o: {readonly kind: "click"}) {}
readKind(e); // Works! См. также
-
Примитивные типы — базовые типы (
number,stringи т. д.), специализацией которых являются литералы - Объединения — часто используются с литералами для определения конечных наборов значений
-
Константные выражения —
as constдля сохранения типов литералов после присваивания, особенно внутри контейнеров -
Вариантность — почему значение
readonlyнельзя передать в слот, доступный для записи - Перечисления Flow — структурированная альтернатива объединениям типов литералов
© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/types/literals