From 11792e0435b3609f1eb68c66b1698a7c29dbe327 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Sat, 24 Dec 2022 20:17:36 +0100 Subject: [PATCH] experiment inferring TS types from a JS template --- src/infer.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/infer.ts diff --git a/src/infer.ts b/src/infer.ts new file mode 100644 index 0000000..baf3d0c --- /dev/null +++ b/src/infer.ts @@ -0,0 +1,57 @@ +/** + * Idea: instead of writing TypeScript, and inferring the JS-pocomath signature + * from TS that via a TypeScript plugin, we can maybe do this the other way + * around: take the JS-pocomath signature as base (and source of truth), and + * infer TypeScript interfaces from that using infer in template literal types. + */ + +type T = {} // TODO: how to do generics? + +const create = createFactory<{ + number: number + bigint: bigint + T: T // TODO: how to do generics? + 'Complex': unknown // TODO: how to do generics? +}>() + + +// TODO: how to pass config? +// FIXME: multiple signatures do not work + +const createSquare = create({ + multiply: '(number, number) : number', + // zero: '(number) : number' + },dep => { + return (x: number) => dep.multiply(x, x) + } +) + +// the code works in JS, and works in TS +const multiply = (a: number, b: number) => a * b +const square = createSquare({ multiply }) +console.log('square', square(8)) // 64 + +function createFactory>() { + type K = string & keyof BaseTypes + + type ResolveType = BaseTypes[T] + + type ResolveTuple = + T extends K ? [ResolveType] : + T extends `${infer L extends K}, ${infer M extends K}` ? [ResolveType, ResolveType] : + T extends `${infer L extends K}, ${infer M extends K}, ${infer N extends K}` + ? [ResolveType, ResolveType, ResolveType] + : never + + type ResolveFunction = + T extends `${infer Name}(${infer Args}) : ${infer L extends K}` + ? (...args: ResolveTuple) => ResolveType + : never + + return function create( + dependencies: { [L in T]: U }, + callback: (deps: { [L in T]: ResolveFunction }) => V + ) { + return callback + } +}