-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Open
Labels
300answerShare answers/solutions to a questionShare answers/solutions to a questionenin Englishin English
Description
300 - String To Number
As of TypeScript 4.8 this has a super trivial one-line solution, but before that it was quite intense. The solutions on this video are more like an archaeological dig than anything else.
🎥 Video Explanation
🔢 Code
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type A1 = ToNumber<'0'>;
type B1 = 0;
type C1 = Expect<Equal<A1, B1>>;
type A2 = ToNumber<'5'>;
type B2 = 5;
type C2 = Expect<Equal<A2, B2>>;
type A3 = ToNumber<'12'>;
type B3 = 12;
type C3 = Expect<Equal<A3, B3>>;
type A4 = ToNumber<'27'>;
type B4 = 27;
type C4 = Expect<Equal<A4, B4>>;
type A5 = ToNumber<'18@7_$%'>;
type B5 = never;
type C5 = Expect<Equal<A5, B5>>;
// // ============= Your Code Here =============
// // /** TypeScript 4.8: https://devblogs.microsoft.com/typescript/announcing-typescript-4-8-beta/#infer-types-template-strings */
// type ToNumber<T> =
// T extends `${infer N extends number}`
// ? N
// : never;
// type ToNumber<
// T extends string,
// Count extends '🧮'[] = []
// > =
// T extends `${number}`
// ? T extends `${Count["length"]}`
// ? Count["length"]
// : ToNumber<T, [...Count, '🧮']>
// : never;
// // ================== NOPE ==================
// // Type instantiation is excessively deep
// // and possibly infinite.ts(2589)
// type ToNumber<
// T extends string,
// Count extends 1[] = []
// > =
// T extends `${Count["length"]}`
// ? Count["length"]
// : ToNumber<T, [...Count, 1]>;
// ============== Alternative ==============
// @uid11
type Num = readonly 0[]
/**
* NumToNumber<Num3> = 3, where Num3 = [0, 0, 0]
*/
type NumToNumber<N extends Num> = N['length']
type Digit =
| '0' | '1' | '2' | '3' | '4'
| '5' | '6' | '7' | '8' | '9'
/**
* MultiplyToDigit<'3', Num2> = Num6
*/
type MultiplyToDigit<D extends Digit, N extends Num> = {
'0': [],
'1': N,
'2': [...N, ...N],
'3': [...N, ...N, ...N],
'4': [...N, ...N, ...N, ...N],
'5': [...N, ...N, ...N, ...N, ...N],
'6': [...N, ...N, ...N, ...N, ...N, ...N],
'7': [...N, ...N, ...N, ...N, ...N, ...N, ...N],
'8': [...N, ...N, ...N, ...N, ...N, ...N, ...N, ...N],
'9': [...N, ...N, ...N, ...N, ...N, ...N, ...N, ...N, ...N],
}[D]
/**
* Num1
*/
type One = [0]
/**
* DigitToNum<'2'> = Num2
*/
type DigitToNum<D extends Digit> = MultiplyToDigit<D, One>
/**
* Sum<Num2, Num3> = Num5
*/
type Sum<N extends Num, M extends Num> = [...N, ...M]
/**
* MultiplyTo10<Num2> = Num20
*/
type MultiplyTo10<N extends Num> =
MultiplyToDigit<
'2',
MultiplyToDigit<'5', N>
>
/**
* GetBase<'2'> = Num10, GetBase<'31'> = Num100
*/
type GetBase<Number extends string> =
Number extends Digit
? MultiplyTo10<One>
: Number extends `${string}${infer Rest}`
? MultiplyTo10<GetBase<Rest>>
: never
/**
* StrToNum<'13'> = Num13
*/
type StrToNum<Str extends string> = Str extends Digit
? MultiplyToDigit<Str, One>
: Str extends `${infer D}${infer Rest}`
? D extends Digit
? Sum<
MultiplyToDigit<D, GetBase<Rest>>,
StrToNum<Rest>
>
: never
: never
/**
* ToNumber<'24'> = 24
*/
type ToNumber<S extends string> = NumToNumber<StrToNum<S>>➕ More Solutions
For more video solutions to other challenges: see the umbrella list! #21338
Metadata
Metadata
Assignees
Labels
300answerShare answers/solutions to a questionShare answers/solutions to a questionenin Englishin English