Repository navigation
Support inferring numeric literal types from their string representations #42938
Description
Activity
RyanCavanaugh commented
on Feb 24, 2021 MemberMore actionsThis isn't really going to do what you want because intersection inference deliberately discards "matching" constituents. e.g.
type Disposable = { dispose(): void }; type FooDisp = { foo: string } & Disposable declare function nondisposable<T>(arg: T & Disposable): T; declare const fd: FooDisp // p: { foo: string } const p = nondisposable(fd);
I would probably write this as
type Converter<D extends number> = D extends unknown ? [`${D}`, D] : never; type Convert = Converter<0 | 1 | 2 | 3 /* etc to some reasonable number */>; type Match<T, U> = T extends [U, infer V] ? V : never; type ToNumber<T extends string> = Match<Convert, T>; const foo: ToNumber<'1'> = 1 // OK
- addedQuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
on Feb 24, 2021 This sounds more like a suggestion that we should support the pattern
`${number & infer T}`to infer a numeric literal type from its equivalent string representation. We currently have no way of doing that, except for limited solutions like the one above.Reacted by DetachHead, Joe Calzaretta, Aleksey Levenstein and Devansh Jethmalani- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptand removedQuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
on Feb 25, 2021 - changed the title
[-]infer keyword doesn't work on intersections[/-][+]Support inferring numeric literal types from their string representations[/+]on Feb 25, 2021 - addedIn DiscussionNot yet reached consensusNot yet reached consensus
on Feb 25, 2021 Is this the official place to 👍 a request for
type StrToNum<S extends string> = ✨🧙♀️🧙♂️✨
which is the inverse of
type NumToStr<N extends number> = `${N}`;
?
If so, 👍!
Reacted by Jeff Zou, DetachHead, Aleksey Levenstein, Tim, Toni Villena, Carter Snook and sebThis isn't really going to do what you want because intersection inference deliberately discards "matching" constituents. e.g.
type Disposable = { dispose(): void }; type FooDisp = { foo: string } & Disposable declare function nondisposable<T>(arg: T & Disposable): T; declare const fd: FooDisp // p: { foo: string } const p = nondisposable(fd);
I would probably write this as
type Converter<D extends number> = D extends unknown ? [`${D}`, D] : never; type Convert = Converter<0 | 1 | 2 | 3 /* etc to some reasonable number */>; type Match<T, U> = T extends [U, infer V] ? V : never; type ToNumber<T extends string> = Match<Convert, T>; const foo: ToNumber<'1'> = 1 // OK
Hello, thank you for your work on TypeScript. Do you have an update on this opinion now with the release of the new recursion improvements? It is now possible to create N-sized addition, subtraction, ect. types that manipulate using string types. I have done this and my integer addition type works for numbers from
0through99999999999999999999999999999999999999999999999and it is A(4n) + B(4n) wherenis equal to the length of the number as a string so there is still room for improvements. It would also be fairly trivial to create a floating point addition type as well using the integral addition type. The largest pitfall, however, is that you cannot convert the string number type that is the result of your operation back into a number type. Of course, you can go with the array accumulator approach where you keep shoving items into an array and check if the length as a string is equal to the number as a string but that is highly inefficient and doesn't include the complexity required for supporting floating point numbers which would definitely only work for a small subset of numbers before having a type overflow. ThanksReacted by KotlinIslandCan this issue be closed, as the desired feature was introduced in #48094?
Reacted by DetachHeadyes it can. for the record here's how to create the
ToNumbertype from my OP:type ToNumber<T extends string> = T extends `${infer Result extends number}`? Result: never
Reacted by Julian Meinking, LufyCZ and Taishi NaritomiReacted by Taishi Naritomi
Bug Report
🔎 Search Terms
infer conditional type intersection
🕗 Version & Regression Information
4.3.0-dev.20210224
Playground link with relevant code
💻 Code
🙁 Actual behavior
Tdoesn't extend${number & infer R}, even though it does extend${number & any}🙂 Expected behavior
Tshould extend${number & infer R}and (if my understanding ofinferis correct)Rshould be1