/** * 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 } }