background:
by const variable with inferred type
, I mean
const c = 1 // this
const c:1 = 1 // not this
const c = 1 as const // not this
So I am trying to narrow down the type of such variable, here is my attempt:
does not work
does not work
export const Narrow=<T extends any>(v:T extends never ? T: T extends never ? T : T)=>{
//
}
const c=1
Narrow(c)
this works, it looks weird, but it did the job
so my question is:
update: as for typescript 5.0, none of the methods work anymore,just use generic cosnt keyword
This has now been addressed in TypeScript 5.0 with the introduction of const
generics. See this pull request and the relevant issue for more information. With this, the definition of Narrow
now looks like
export const Narrow = <const T>(v: T) => {};
const c = 1;
Narrow(c); // inferred as Narrow<1>(v: 1)
This acts in a similar manner to the Narrow
type I showcased in the comments:
type Narrow<T> =
| (T extends infer U ? U : never)
| Extract<T, number | string | boolean | bigint | symbol | null | undefined | []>
| ([T] extends [[]] ? [] : { [K in keyof T]: Narrow<T[K]> });
Except that it infers everything as readonly, as if you had really called the function with
Narrow({ ... } as const)
You can compare the pre-5.0 method and 5.0 const generics using the two playground links below: