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

Use of values instead of types in conditional types

I’d like to have a time type (00:00) which is a string that only allows valid times. Consider this Time type working as I like:

const hours = [
  '00' , '01', '02', '03', '04', '05', '06', '07', '08',
  '09' , '10', '11', '12', '13', '14', '15', '16', 
  '17' , '18', '19', '20', '21', '22', '23', '24'
] as const

type HH = typeof hours[number]

const minutes = [
  '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', 
  '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', 
  '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', 
  '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', 
  '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', 
  '50', '51', '52', '53', '54', '55', '56', '57', '58', '59'
] as const 

type MM = typeof minutes[number]

type Time = `${HH}:${MM}`

A cleaner way to write this type can be:

const digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ] as const
type Digit = typeof digits[number]
type HH1 = `${Digit}${Digit}` // can be 99, needs to be < 24!
type MM1 = `${Digit}${Digit}` // can be 99, needs to be < 60!
type Time1 = `${HH1}:${MM1}$` // can be 99:99, needs to be max 24:59

So I am trying to use the number array index value of the type typeof digits[number] or the output string value to achieve hours to be < 24 and minutes < 60. Can I use the number value instead of the type or the string value to achieve this in a conditional type?

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

>Solution :

Since TS 4.5 you can do following :

type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N
  ? Acc[number]
  : Enumerate<N, [...Acc, Acc['length']]>

type NumberRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>

type Time = NumberRange<0, 59> // 0...59

That’s until, we get ranges as number type in TS.

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