Last active
February 4, 2022 00:04
-
-
Save zachhardesty7/4b88be5dbc4ce1d00c37df0d1811c48b to your computer and use it in GitHub Desktop.
TypeScript Types binary to decimal exploration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copyright 2022 Zach Hardesty | |
// want to check this out in the TypeScript playground? | |
// visit the following link to automatically see the latest version! | |
// https://www.typescriptlang.org/play?jsx=0#gist/4b88be5dbc4ce1d00c37df0d1811c48b | |
// experiments that have thus far been unsuccessful | |
// https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f | |
// https://github.com/fightingcat/sits | |
// https://github.com/kddnewton/typescript-parse-math | |
// https://github.com/ronami/meta-typing | |
// https://github.com/ghoullier/awesome-template-literal-types#bitwise-arithmetic | |
// https://www.typescriptlang.org/play?ts=4.5.0-dev.20210908#code/C4TwDgpgBAsgggDQJIwKowPpwDLYPIDqAogCIYBCeqAciXAEoCaUAvFACwCcArALABQA0JFgBDMJAAmAHgFR5UalAgAPYBAB2kgM5QNAVwC2AIwgAnADRyF9CNv0AbYMrWadUOGbOiQ0-RoBrDQB7AHcNAD5WKABtAF0rfgUoKJZreQAKW3snGIByB00Ac2AACzy4l3UtXWp05KgAfihsx2B65IAuMQkIGWoLWIA6EdanQbHgfMKNEvK4uIj6gEoBAQB6dagABihBgEZBgCYoEaGOTnYhcGhqI1MzelFZ6DYYcSlpeGQ0TBx8YhkSg0OhMCIxAwmcxxNaCfjCaAAFVUwG00kRVTcugACmZgpAzKAANIQECpKAYlFYvT3cxNKAAA3UagAJABvREAXwZUG6GggADdzLDriIMWwDA4HFAAD5QABEon0wGC8tlFJRaLuUMezyKEAiAG5YQioCQAJYAY2A5uCGlEZhA0TZ9RiuPxUHNGkUtN1Lygol0DPZ7rA3Li3VDAk5sM28l2cv26pOcoAzOr2OruOqAGzqgDs6oAHOrOOr9rszhcrvCbopWPUiGpvNb0YMmSj2ZCHtyolSaozmcB2V6AGZ0+jc+rNeiYgcBUnBUdmq02u0OkDTlfW232x0xegwpIKPmC4XH+SnoVmEX8IA | |
// https://www.typescriptlang.org/play?ts=4.5.0-dev.20211012#code/C4TwDgpgBAsgggDQJIwKowPpwDLYPIDqAogCIYBCeqAciXAEoCaUAvFAJycCwAUL6JFgBDMJAAmAHl5QZUalAgAPYBAB2YgM5RVAVwC2AIwgAnADTTZ9CBp0AbYAuVrNUOMeNCQEnaoDWqgHsAd1UAPlYoAG0AXXMeWShwlgsZAAorG3tIgHJbNQBzYAALbOjHFXUtahSEqAB+KAy7YBqEgC5hUQhJalMogDpBpvs+4eAcvNVCkujo0JqASl5lngFoan0jY3ohKeg2GBFxCXhkNEwcfGIySho6JlDI3UMTaJX+cGgAYQDVADcTMAACoBDYvYwSIHlZxaDTAYwASymo12+WgSgqLmeWySNXSqPRTkqUF2IFasgaqQABgASADeOz2AF8qdDiUDybV6o0CZzah1VBAAcYlvEuVABUKTKKPoIMBEfv9ASCwVsJNkAKzZPqqkyMtHhAD0hqgGtl0Aw8rYiuFwNBmxM6oAjAAmLU6h3bAlGk2us18HhAA | |
// https://www.typescriptlang.org/play?ts=4.5.0-dev.20211012&ssl=9&ssc=25&pln=9&pc=31#code/C4TwDgpgBAsgggDQJIwKowPpwDLYPIDqAogCIYBCeqAciXAEoCaUAvFAJycCwAUL6JFgBDMJAAmAHl5QZUalAgAPYBAB2YgM5RVAVwC2AIwgAnADTTZ9CBp0AbYAuVrNUOMeNCQEnaoDWqgHsAd1UAPlYoAG0AXXMeWShwlgsZAAorG3tIgHJbNQBzYAALbOjHFXUtahSEqAB+KAy7YBqEgC5hUQhJalMogDpBpvs+4eAcvNVCkujo0JqASl5lngFoan0jY3ohKeg2GBFxCXhkNEwcfGIySho6JlCAbhX+cGgAYQDVADcTYAAVAIbQwmCT-crOLQaYDGACWU1Gu3y0CUFRcuhBxhiSQs4NRkKgvggIACADNGkjoA0dntIv8yh1VBBfsZnnxVm8oBgIp8fn9AcCthJsgBWbJ9QUmGnI8IAellUBFr0EGG5bF5LIBQM2oOyAEYAExiiU67aUuUKw1K9lAA | |
type decimalMapA = { | |
"0000": "0" | |
"0001": "1" | |
"0010": "2" | |
"0011": "3" | |
"0100": "4" | |
"0101": "5" | |
"0110": "6" | |
"0111": "7" | |
"1000": "8" | |
"1001": "9" | |
} | |
/** numbers with a carried digit in base 10 */ | |
type decimalMapB = { | |
"1010": "0" | |
"1011": "1" | |
"1100": "2" | |
"1101": "3" | |
"1110": "4" | |
"1111": "5" | |
} | |
type decimalMapInc = { | |
"0": "1" | |
"1": "2" | |
"2": "3" | |
"3": "4" | |
"4": "5" | |
"5": "6" | |
"6": "7" | |
"7": "8" | |
"8": "9" | |
"9": "0" | |
} | |
type IncDecCarry<Dec extends string> = Dec extends keyof decimalMapInc | |
? Dec extends "9" | |
? [decimalMapInc[Dec], One] | |
: [decimalMapInc[Dec], Zero] | |
: never | |
/** note, must be multiple of 4, well exactly 4 bc this algorithm isn't how math works... */ | |
type binToDecString< | |
Bin extends string, | |
Out extends string = "", | |
Carry extends string = Zero, | |
> = Bin extends "" | |
? Carry extends One | |
? `1${Out}` | |
: Out | |
: Bin extends `${infer Rest}${Nibble}` | |
? Bin extends `${Rest}${infer D}` | |
? D extends keyof decimalMapA | |
? Carry extends One | |
? binToDecString< | |
Rest, | |
`${IncDecCarry<decimalMapA[D]>[0]}${Out}`, | |
IncDecCarry<decimalMapA[D]>[1] | |
> | |
: binToDecString<Rest, `${decimalMapA[D]}${Out}`, Zero> | |
: D extends keyof decimalMapB | |
? binToDecString<Rest, `${decimalMapB[D]}${Out}`, One> | |
: never | |
: never | |
: never | |
type TEST_DEC_00 = Expect<binToDecString<"0111">, "7"> | |
type TEST_DEC_01 = Expect<binToDecString<"0000">, "0"> | |
type TEST_DEC_02 = Expect<binToDecString<"1010">, "10"> | |
type TEST_DEC_03 = Expect<binToDecString<"1111">, "15"> | |
// type TEST_DEC_04 = Expect<binToDecString<"00101010">, "42"> | |
// subtract 9 in a loop? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment