Skip to content

Instantly share code, notes, and snippets.

@m93a
Last active June 20, 2024 09:33
Show Gist options
  • Save m93a/57c7073065f34ef87879116f484f86bc to your computer and use it in GitHub Desktop.
Save m93a/57c7073065f34ef87879116f484f86bc to your computer and use it in GitHub Desktop.
TypeScript type-level unsigned integer addition – add together two number literals.
declare const Zero: unique symbol;
type Zero = { [Zero]: true };
declare const Succ: unique symbol;
type Succ<T> = { [Succ]: T };
type FirstElementOrZero<Arr extends any[]>
= Arr extends []
? Zero
: Arr[0];
type EncodeNat<n extends number, Acc extends any[] = []>
= Acc['length'] extends n
? FirstElementOrZero<Acc>
: EncodeNat<n, [Succ<FirstElementOrZero<Acc>>, ...Acc]>;
type DecodeNat<N, Acc extends any[] = []>
= N extends Succ<infer M>
? DecodeNat<M, [0, ...Acc]>
: Acc['length'];
type AddEncoded<L, R>
= L extends Succ<infer M>
? AddEncoded<M, Succ<R>>
: R;
type Add<l extends number, r extends number>
= l extends any ? r extends any ?
DecodeNat<
AddEncoded<
EncodeNat<l>,
EncodeNat<r>
>
>
: never : never;
const _: Add<5, 1 | 2> = 7;
@m93a
Copy link
Author

m93a commented Jun 20, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment