Feature Request: const modifier on type parameters ยท Issue #46937 ยท microsoft/TypeScript (original) (raw)

Suggestion

๐Ÿ” Search Terms

const readonly modifier assertion immutable

โœ… Viability Checklist

My suggestion meets these guidelines:

โญ Suggestion

Generic functions in TypeScript automatically infer type parameters by its parameters, which is convenient and intelligent.

declare function foo(value: T): T

foo({ a: 1 }) // { a: number } foo([1, '2']) // (number | string)[]

Sometimes we want to get a more specific inference (asserting some value a is "constant" or "type immutable"):

foo({ a: 1 } as const) // { readonly a: 1 } foo([1, '2'] as const) // readonly [1, '2']

However, some functions are designed to do such things, which means users should always add "as const" whenever they call it. Can we just place the constant asserting into function declaration?

๐Ÿ“ƒ Motivating Example

declare function foo(value: const T): T

foo({ a: 1 }) // { readonly a: 1 } foo([1, '2']) // readonly [1, '2']

Alternative:

// use "readonly" instead of "const" declare function foo(value: readonly T): T

๐Ÿ’ป Use Cases

It will be really useful for underlying libraries, such as schema validatation.

declare type Schema<T = any> = (value: T) => T

declare function number(): Schema declare function string(): Schema

// case 1: tuple type

declare type TypeOf = S extends Schema ? T : never declare type TupleOf<X extends readonly unknown[]> = X extends readonly [infer L, ...infer R] ? readonly [TypeOf, ...TupleOf] :[]

declare function tuple<X extends readonly Schema[]>(list: const X): Schema<TupleOf>

tuple([number(), string()]) // Schema<readonly [number, string]>

// case 2: union type

declare function union(list: readonly X[]): Schema<TypeOf> declare function constant(value: const T): Schema

union([number(), string()]) // Schema<number | string> union([constant(1), constant('2')]) // Schema<1 | '2'>

playground without suggested syntax