Closed
Description
Search Terms
Const Type Constraint Literal
Suggestion
Add new syntax const T
or a global generic type Constant<T = any> = T extends const T ? T : never;
type ConstString = const string
is same as type ConstString = Constant<string>
.
- If
T
extendsstring | number | boolean | symbol | bigint | null | undefined
, requiresT
to be a constant. - If
T
isobject
orArray
, requires every member ofT
to be a constant. - If
T
isenum
, nothing to do, becauseenum
is same asconst enum
The difference with union literal is that type 'foo' | 'bar'
can only be 'foo' or 'bar', but type const string
can be any constant string.
Use Cases
- Sometimes we want to constrain a type or a parameter to be literal.
- It can help the TS compiler to recognize constant types better
Examples
let foo = 'foo'; // string
const bar= 'bar'; // 'bar'
const notConstant: const string = foo; // error
const trulyConstant: const string = bar; // success
type Baz = { baz: string } ;
const baz1: const Baz = { baz: 'baz' }; // success
const baz2: Baz = { baz: 'baz' }; // not a constant
const baz3: Baz = { baz: 'baz' } as const; // current available, same as baz1
type ConstArray<T> = const Array<T>;
// same as
type AnotherCosntArray<T> = Array<const T>;
function tuple<T extends ConstArray>(...args: T) {
return args;
}
const t1 = tuple(foo); // error!
const t2 = tuple(bar); // success! typeof t2 should be ['bar']
const t3 = tuple('a', 1, true, ['1'], baz1) // ['a', 1, true, ['1'], { baz: 'baz' }];
const t4 = tuple(baz2) // error!
let variable: const string = 'variable'; // this is possible
variable = 'another variable'; // success
variable = document.title; // error
let reactiveObject: const { foo: string } = { foo: 'foo' }; // success;
reactiveObject.foo = 'bar' // success
In fact, const
only affects the assignment behavior, and a const
type is considered to be the same as a non const
type when read it.
A const type
doesn't mean immutable, just means every primitive value should be literal, so maybe should call it literal type
.
Alternatives
- Only add
extends const
syntax, and add global generictype Constant<T = any> = T extends const ? T : never;
- Use
finally
orstatic
orliteral
(not exist in current keywords) keyword instead ofconst
- Use
type Literal
instead oftype Constant
.
Related issues
#30680 Suggestion: Const contexts for generic type inference
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment