Acid Coder
Acid Coder

Reputation: 2756

Typescript narrow down generic type of const variable with inferred type

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

related

So I am trying to narrow down the type of such variable, here is my attempt: enter image description here

does not work

enter image description here

does not work

enter image description here

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

playground

so my question is:

  1. why?
  2. any simpler solution?
  3. any better solution?

update: as for typescript 5.0, none of the methods work anymore,just use generic cosnt keyword

Upvotes: 2

Views: 398

Answers (1)

tenshi
tenshi

Reputation: 26404

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:

Upvotes: 4

Related Questions