-
as const
can be used to mark a value as deeply readonly - i.e., it can't be mutated in any way. -
It's different from
Object.freeze
in two ways. First, it only runs at compile-time, so it disappears at runtime. Second,Object.freeze
only works on the top level.as const
works on the entire object.
ts
constobj = {foo : {bar : 42,},} asconst ;// Error!Cannot assign to 'bar' because it is a read-only property.2540Cannot assign to 'bar' because it is a read-only property.obj .foo .= 43; bar constfreezedObj =Object .freeze ({foo : {bar : 42,},});// Works!freezedObj .foo .bar = 43;
- It's useful on objects, but can also be used on arrays to turn them into readonly tuples:
ts
constarr = [1, 2, 3] asconst ;Property 'push' does not exist on type 'readonly [1, 2, 3]'.2339Property 'push' does not exist on type 'readonly [1, 2, 3]'.arr .(4); push
- Objects and arrays marked with
as const
get inferred as their literal types, not the wider types. This can be useful for creating type-safe enums without needing theenum
keyword.
ts
constobj = {foo : {bar : 42,},};// Inferred as numberconsole .log (obj .foo .bar );constobj2 = {foo : {bar : 42,},} asconst ;// Inferred as its literal!console .log (obj2 .foo .bar );
as const
can also be used to force values to infer as narrowly as possible - for instance, inside objects:
ts
constbuttonProps = {type : "button" asconst ,onClick : () => {console .log ("clicked");},} asconst ;// Inferred as "button", not stringconsole .log (buttonProps .type );
- It can also be used to encourage a function that returns an array to infer as a tuple:
ts
declare constuseState : () => [string,(newState : string) => void];constuseStateWrapped = () => {const [state ,setState ] =useState ();return [state ,setState ] asconst ;};
Share this TypeScript Concept with your friends