Const contexts for literal expressions by ahejlsberg · Pull Request #29510 · microsoft/TypeScript (original) (raw)
With this PR we introduce const
assertions which favor immutability in the types inferred for literal expressions (inspired by suggestions in #10195, #20195, and #26979). A const
assertion is simply a type assertion that uses the reserved word const
as the type name:
let x = 10 as const; // Type 10 let y = [10, 20]; // Type readonly [10, 20] let z = { text: "hello" } as const; // Type { readonly text: "hello" }
A const
assertion establishes a const context in which
- string, numeric, and boolean literals have non-widening literals types (see Non-widening explicit literal types #11126),
- array literals have read-only tuple types (see Improved support for read-only arrays and tuples #29435), and
- object literals have read-only properties.
Const contexts do not otherwise affect types of expressions, and expressions in const contexts never have a contextual type.
An expression x
is said to occur in a const context if x
is
- the operand of a
const
assertion, or - a parenthesized expression that occurs in a const context, or
- an element of an array literal that occurs in a const context, or
- the expression of a property assignment in an object literal that occurs in a const context, or
- a spread expression that occurs in a const context.
Note in particular that const contexts extend into nested array and object literals. For example, the declaration
let obj = { x: 10, y: [20, 30], z: { a: { b: 42 } } } as const;
corresponds to
let obj: { readonly x: 10; readonly y: readonly [20, 30]; readonly z: { readonly a: { readonly b: 42; }; }; };
A const
assertion requires the operand to be a string, number, bigint, boolean, array, or object literal, optionally enclosed in one or more levels of parentheses. It is an error to apply a const
assertion to expressions of other forms.