Defined the signature of the function that is being created too

This commit is contained in:
Jos de Jong 2023-09-14 19:31:21 +02:00
parent 7dc26ea297
commit a4f5af3ea5

View File

@ -9,19 +9,19 @@ const create = createFactory<{
number: number number: number
bigint: bigint bigint: bigint
string: string string: string
// T: T // TODO: how to do generics? any: any
// 'Complex<T>': unknown // TODO: how to do generics?
}>() }>()
// These are our string based interfaces, which we can use both in typed-function and in TypeScript:
// TODO: how to pass config?
// These are the interfaces:
const Multiply = 'multiply(number,number)=>number' const Multiply = 'multiply(number,number)=>number'
const Sqrt = 'sqrt(number)=>number'
const Zero = 'zero(number)=>number' const Zero = 'zero(number)=>number'
// TODO: get generics working
// TODO: how to pass config?
const createSquare = create([Multiply, Zero],dep => { const createSquare = create(Sqrt, [Multiply, Zero],dep =>
return (x: number) => dep.multiply(x, x) x => dep.multiply(x, x)
}) )
// the code works in JS, and works in TS // the code works in JS, and works in TS
const multiply = (a: number, b: number) => a * b const multiply = (a: number, b: number) => a * b
@ -43,15 +43,22 @@ function createFactory<BaseTypes extends Record<string, unknown>>() {
? [ResolveType<Arg>] ? [ResolveType<Arg>]
: never : never
type FunctionDefinition<FnType> = type DependencyRecord<FnType> =
FnType extends Value<infer K> FnType extends Value<infer K>
? K extends `${infer Name}(${infer Args})=>${infer ReturnType extends BaseTypeNames}` ? K extends `${infer Name}(${infer Args})=>${infer ReturnType extends BaseTypeNames}`
? Record<Name, (...args: ResolveArguments<Args>) => ResolveType<ReturnType>> ? Record<Name, (...args: ResolveArguments<Args>) => ResolveType<ReturnType>>
: never : never
: never : never
type CreatedFunctionType<FnType> =
FnType extends Value<infer K>
? K extends `${infer Name}(${infer Args})=>${infer ReturnType extends BaseTypeNames}`
? (...args: ResolveArguments<Args>) => ResolveType<ReturnType>
: never
: never
// inspired by: https://stackoverflow.com/questions/68391632/infer-type-from-array-literal // inspired by: https://stackoverflow.com/questions/68391632/infer-type-from-array-literal
type DepRecord< type DependenciesRecord<
Arr extends Array<Value<any>>, Arr extends Array<Value<any>>,
Result extends Record<string, any> = {} Result extends Record<string, any> = {}
> = Arr extends [] > = Arr extends []
@ -59,16 +66,17 @@ function createFactory<BaseTypes extends Record<string, unknown>>() {
: Arr extends [infer H, ...infer Tail] : Arr extends [infer H, ...infer Tail]
? Tail extends Array<Value<any>> ? Tail extends Array<Value<any>>
? H extends Value<any> ? H extends Value<any>
? DepRecord<Tail, Result & FunctionDefinition<H>> ? DependenciesRecord<Tail, Result & DependencyRecord<H>>
: never : never
: never : never
: never : never
return function create<K extends string, Dependencies extends Value<K>[], W>( return function create<K extends string, Dependencies extends Value<K>[], W extends Value<K>>(
signature: W,
dependencies: [...Dependencies], dependencies: [...Dependencies],
callback: (deps: DepRecord<[...Dependencies]>) => W callback: (deps: DependenciesRecord<[...Dependencies]>) => CreatedFunctionType<W>
) { ) {
console.log('Creating typed-function with dependencies:', dependencies) console.log('Creating typed-function with', { signature, dependencies })
// TODO: create a typed-function for real // TODO: create a typed-function for real
return callback return callback
} }