Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Detecting type literals works in isolation but not when combined with other literal types

I have a series of type utilities which test whether a given type <T> is the literal or wide variant of the type:

  • IsStringLiteral<T extends string>
  • IsNumericLiteral<T extends number>
  • IsBooleanLiteral<T extends boolean>

I then wanted to wrap these utilities into a single utility IsLiteral which looks like the following:

export type IsLiteral<T extends string | number | boolean> = T extends string
  ? IsStringLiteral<T>
  : T extends boolean
    ? IsBooleanLiteral<T>
    : T extends number
      ? IsNumericLiteral<T>
      : never;

I am running type tests on all of the individual utilities as well as my master blaster IsLiteral and everything works … except I get a false positive for booleans when I test IsLiteral<boolean> and yet IsBooleanLiteral<boolean> works as expected.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You can find info on the IsLiteral here: [ definition, test ]

Here’s an inline version of the test which fails:

enter image description here

>Solution :

This is because boolean is internally represented as true | false. That means it’ll be distributed in this conditional:

  : T extends boolean
    ? IsBooleanLiteral<T>

and it’ll now be:

(true extends boolean ? IsBooleanLiteral<true> : ...) | (false extends boolean ? IsBooleanLiteral<false> : ...)

which simplifies to:

IsBooleanLiteral<true> | IsBooleanLiteral<false>

both of which are true, so you get true for boolean. You can avoid this by wrapping it in a tuple. This is described in distributive conditional types in the handbook:

  : [T] extends [boolean]
    ? IsBooleanLiteral<T>

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading