Skip to content

Instantly share code, notes, and snippets.

@luizstacio
Last active October 11, 2022 15:34
Show Gist options
  • Save luizstacio/b33b62c6c84375081f37ac563a6f6a20 to your computer and use it in GitHub Desktop.
Save luizstacio/b33b62c6c84375081f37ac563a6f6a20 to your computer and use it in GitHub Desktop.
JSON generate typed functions
const functions = [
{
name: 'foo',
params: [
{
name: 'a',
type: 'string',
},
{
name: 'b',
type: 'number',
},
],
},
{
name: 'bar',
params: [
{
name: 'c',
type: 'string',
},
{
name: 'd',
type: 'number',
},
],
},
] as const;
// Type Decoder from String
type TypesMap<T> = T extends 'string' ? string : number;
// Union to tuple utilities
type TuplePrepend<Tuple extends readonly unknown[], NewElement> = [
NewElement,
...Tuple
];
type Consumer<Value> = (value: Value) => void;
type IntersectionFromUnion<Union> = (
Union extends unknown ? Consumer<Union> : never
) extends Consumer<infer ResultIntersection>
? ResultIntersection
: never;
type OverloadedConsumerFromUnion<Union> = IntersectionFromUnion<
Union extends unknown ? Consumer<Union> : never
>;
type UnionLast<Union> = OverloadedConsumerFromUnion<Union> extends (
a: infer A
) => void
? A
: never;
type UnionExcludingLast<Union> = Exclude<Union, UnionLast<Union>>;
type TupleFromUnionRec<
RemainingUnion,
CurrentTuple extends readonly unknown[]
> = [RemainingUnion] extends [never]
? CurrentTuple
: TupleFromUnionRec<
UnionExcludingLast<RemainingUnion>,
TuplePrepend<CurrentTuple, UnionLast<RemainingUnion>>
>;
type TupleFromUnion<Union> = TupleFromUnionRec<Union, []>;
// Array to object function
type FuncDec<
T extends Array<{ name: string; type: string }>,
Args = {
[TIndex in T[number] as TypesMap<TIndex['type']>]: boolean;
}
> = (...args: TupleFromUnion<keyof Args>) => void;
type AbiFuncs<T extends ReadonlyArray<{ name: string; params: any }>> = {
[I in T[number] as I['name']]: FuncDec<I['params']>;
};
// Array to object function
const x: AbiFuncs<typeof functions> = {} as any;
x.foo('test', 1);
// @ts-expect-error
x.foo(1, 'test');
@luizstacio
Copy link
Author

Also it looks like to re-order the tuple wich leads to issues on the order of arguments

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