Last active
August 1, 2021 16:00
-
-
Save bingo347/00652993abf31702cdbfb6c109af5fbf to your computer and use it in GitHub Desktop.
Typescript arithmetic example
This file contains hidden or 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
type Computable | |
= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
| 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 | |
| 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | |
| 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | |
| 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | |
| 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99; | |
type NextComputable<N extends Computable> = { | |
0: 1; 1: 2; 2: 3; 3: 4; 4: 5; 5: 6; 6: 7; 7: 8; 8: 9; 9: 10; | |
10: 11; 11: 12; 12: 13; 13: 14; 14: 15; 15: 16; 16: 17; 17: 18; 18: 19; 19: 20; | |
20: 21; 21: 22; 22: 23; 23: 24; 24: 25; 25: 26; 26: 27; 27: 28; 28: 29; 29: 30; | |
30: 31; 31: 32; 32: 33; 33: 34; 34: 35; 35: 36; 36: 37; 37: 38; 38: 39; 39: 40; | |
40: 41; 41: 42; 42: 43; 43: 44; 44: 45; 45: 46; 46: 47; 47: 48; 48: 49; 49: 50; | |
50: 51; 51: 52; 52: 53; 53: 54; 54: 55; 55: 56; 56: 57; 57: 58; 58: 59; 59: 60; | |
60: 61; 61: 62; 62: 63; 63: 64; 64: 65; 65: 66; 66: 67; 67: 68; 68: 69; 69: 70; | |
70: 71; 71: 72; 72: 73; 73: 74; 74: 75; 75: 76; 76: 77; 77: 78; 78: 79; 79: 80; | |
80: 81; 81: 82; 82: 83; 83: 84; 84: 85; 85: 86; 86: 87; 87: 88; 88: 89; 89: 90; | |
90: 91; 91: 92; 92: 93; 93: 94; 94: 95; 95: 96; 96: 97; 97: 98; 98: 99; 99:never; | |
}[N]; | |
type PrevComputable<N extends Computable> = { | |
0:never; 1: 0; 2: 1; 3: 2; 4: 3; 5: 4; 6: 5; 7: 6; 8: 7; 9: 8; | |
10: 9; 11: 10; 12: 11; 13: 12; 14: 13; 15: 14; 16: 15; 17: 16; 18: 17; 19: 18; | |
20: 19; 21: 20; 22: 21; 23: 22; 24: 23; 25: 24; 26: 25; 27: 26; 28: 27; 29: 28; | |
30: 29; 31: 30; 32: 31; 33: 32; 34: 33; 35: 34; 36: 35; 37: 36; 38: 37; 39: 38; | |
40: 39; 41: 40; 42: 41; 43: 42; 44: 43; 45: 44; 46: 45; 47: 46; 48: 47; 49: 48; | |
50: 49; 51: 50; 52: 51; 53: 52; 54: 53; 55: 54; 56: 55; 57: 56; 58: 57; 59: 58; | |
60: 59; 61: 60; 62: 61; 63: 62; 64: 63; 65: 64; 66: 65; 67: 66; 68: 67; 69: 68; | |
70: 69; 71: 70; 72: 71; 73: 72; 74: 73; 75: 74; 76: 75; 77: 76; 78: 77; 79: 78; | |
80: 79; 81: 80; 82: 81; 83: 82; 84: 83; 85: 84; 86: 85; 87: 86; 88: 87; 89: 88; | |
90: 89; 91: 90; 92: 91; 93: 92; 94: 93; 95: 94; 96: 95; 97: 96; 98: 97; 99: 98; | |
}[N]; | |
type AddComputableBasis<N extends Computable> = { | |
[I in Computable]: I extends 0 ? N : NextComputable<AddComputableBasis<N>[PrevComputable<I>]>; | |
}; | |
type SubComputableBasis<N extends Computable> = { | |
[I in Computable]: I extends 0 ? N : PrevComputable<SubComputableBasis<N>[PrevComputable<I>]>; | |
}; | |
type AddComputable<N extends Computable, M extends Computable> = AddComputableBasis<N>[M]; | |
type SubComputable<N extends Computable, M extends Computable> = SubComputableBasis<N>[M]; | |
// examples: | |
const _add_7_5_ok: AddComputable<7, 5> = 12; // ok | |
const _add_7_5_err: AddComputable<7, 5> = 11; // err | |
const _sub_7_5_ok: SubComputable<7, 5> = 2; // ok | |
const _sub_7_5_err: SubComputable<7, 5> = 3; // err |
This file contains hidden or 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
type Test = Sum<2143, 174>; | |
const test: Test = '2317'; | |
const testError: Test = '2318'; | |
type Basis = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; | |
type Digit = Basis[number]; | |
type Stringify<N extends number> = `${N}`; | |
type DigitArray = Stringify<Digit>[]; | |
type DigitMap = { | |
[D in Digit as Stringify<D>]: D; | |
}; | |
type SplitNumber<S extends `${number}`> = S extends Stringify<Digit> | |
? [S] | |
: S extends `${infer D}${infer Tail}` | |
? [...SplitNumber<Tail & `${number}`>, D & Stringify<Digit>] | |
: never; | |
type SplitArray<A extends DigitArray, End extends DigitArray = ['0']> = A extends [infer D, ...infer Tail] | |
? [DigitMap[D & Stringify<Digit>], Tail] | |
: [0, End]; | |
type RevertedBasis = { | |
[D in Digit as Basis[D]]: D; | |
}; | |
type DigitSums = { | |
[D1 in Digit]: { | |
[D2 in Digit]: D2 extends 0 | |
? { | |
digit: D1; | |
shift: false; | |
} | |
: { | |
digit: Basis[DigitSums[D1][RevertedBasis[D2]]['digit']]; | |
shift: DigitSums[D1][RevertedBasis[D2]]['shift'] extends true | |
? true | |
: DigitSums[D1][RevertedBasis[D2]]['digit'] extends 9 | |
? true | |
: false; | |
}; | |
}; | |
}; | |
type SumDigits< | |
D1 extends Digit, | |
D2 extends Digit, | |
Shift extends boolean, | |
> = Shift extends false | |
? DigitSums[D1][D2] | |
: D1 extends 9 | |
? { | |
digit: D2; | |
shift: true; | |
} | |
: DigitSums[Basis[D1]][D2] | |
type SumCalculatorInternal< | |
D1 extends DigitArray, | |
D2 extends DigitArray, | |
R extends DigitArray, | |
Shift extends boolean, | |
> = D1 extends [] | |
? [...R, ...D2] | |
: D2 extends [] | |
? [...R, ...D1] | |
: SumCalculatorInternal< | |
SplitArray<D1>[1], | |
SplitArray<D2>[1], | |
[...R, Stringify<SumDigits<SplitArray<D1>[0], SplitArray<D2>[0], Shift>['digit']>], | |
SumDigits<SplitArray<D1>[0], SplitArray<D2>[0], Shift>['shift'] | |
>; | |
type CollectResult<D extends DigitArray, R extends string = ''> = D extends [] | |
? R | |
: CollectResult<SplitArray<D, []>[1], `${SplitArray<D>[0]}${R}`>; | |
type SumCalculator<D1 extends number, D2 extends number> = SumCalculatorInternal< | |
SplitNumber<Stringify<D1>>, | |
SplitNumber<Stringify<D2>>, | |
[], | |
false | |
> | |
type Sum<D1 extends number, D2 extends number> = CollectResult<SumCalculator<D1, D2> extends DigitArray | |
? SumCalculator<D1, D2> | |
: never>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Playground for new example