From 7dc26ea297eb50923d85f17fdf74bcdfb4e73dd1 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 14 Sep 2023 17:42:42 +0200 Subject: [PATCH] get template literals working with multiple dependencies --- .gitignore | 1 + README.md | 2 +- package.json5 | 2 +- pnpm-lock.yaml | 13 +++++--- src/infer.ts | 84 ++++++++++++++++++++++++++++++-------------------- tsconfig.json | 2 +- 6 files changed, 63 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index df7c548..c3b8f6b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Typescript # emitted code obj +build # ---> Node # Logs diff --git a/README.md b/README.md index 34649c2..1c75e65 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # typocomath -A final (?) prototype for a refactor of mathjs, culminating the picomath, pocomath, typomath series. Provides an extensible core with "fuzzy" types for its operations, that can at any time generate exact .d.ts file for its current state. \ No newline at end of file +A final (?) prototype for a refactor of mathjs, culminating the picomath, pocomath, typomath series. Provides an extensible core with "fuzzy" types for its operations, that can at any time generate exact .d.ts file for its current state. diff --git a/package.json5 b/package.json5 index 874d5e3..5c19d9e 100644 --- a/package.json5 +++ b/package.json5 @@ -4,7 +4,7 @@ description: 'A hopeful final typescipt-pragmatic mathjs proof-of-concept', main: 'index.ts', scripts: { - test: 'echo "Error: no test specified" && exit 1', + go: 'tsc && node build/infer.js' }, keywords: [ 'math', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 095704b..c9669ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,14 +1,17 @@ -lockfileVersion: 5.4 +lockfileVersion: '6.0' -specifiers: - typescript: ^4.9.3 +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false devDependencies: - typescript: 4.9.3 + typescript: + specifier: ^4.9.3 + version: 4.9.3 packages: - /typescript/4.9.3: + /typescript@4.9.3: resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} engines: {node: '>=4.2.0'} hasBin: true diff --git a/src/infer.ts b/src/infer.ts index 7071c7b..e3aa2b6 100644 --- a/src/infer.ts +++ b/src/infer.ts @@ -5,53 +5,71 @@ * 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? + number: number + bigint: bigint + string: string + // 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 +// These are the interfaces: +const Multiply = 'multiply(number,number)=>number' +const Zero = 'zero(number)=>number' -const createSquare = create({ - multiply: '(number, number) : number', - // zero: '(number) : number' - },dep => { - return (x: number) => dep.multiply(x, x) - } -) +const createSquare = create([Multiply, Zero],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 }) +const zero = (a: number) => 0 +const square = createSquare({ multiply, zero }) console.log('square', square(8)) // 64 function createFactory>() { - type K = string & keyof BaseTypes + type BaseTypeNames = string & keyof BaseTypes + type ResolveType = BaseTypes[TypeName] - type ResolveType = BaseTypes[T] + type Value = K - type ResolveArguments = - S extends '' ? [] : - S extends `${infer T extends K}, ${infer U}` - ? [ResolveType, ...ResolveArguments] - : S extends `${infer T extends K}` ? [ResolveType] - : never; + type ResolveArguments = S extends '' + ? [] + : S extends `${infer Arg extends BaseTypeNames},${infer Tail}` + ? [ResolveType, ...ResolveArguments] + : S extends `${infer Arg extends BaseTypeNames}` + ? [ResolveType] + : never - type ResolveFunctionDef = - T extends `${infer Name}(${infer Args}) : ${infer L extends K}` - ? (...args: ResolveArguments) => ResolveType - : never + type FunctionDefinition = + FnType extends Value + ? K extends `${infer Name}(${infer Args})=>${infer ReturnType extends BaseTypeNames}` + ? Record) => ResolveType> + : never + : never - return function create( - dependencies: { [L in T]: U }, - callback: (deps: { [L in T]: ResolveFunctionDef }) => V - ) { - return callback - } + // inspired by: https://stackoverflow.com/questions/68391632/infer-type-from-array-literal + type DepRecord< + Arr extends Array>, + Result extends Record = {} + > = Arr extends [] + ? Result + : Arr extends [infer H, ...infer Tail] + ? Tail extends Array> + ? H extends Value + ? DepRecord> + : never + : never + : never + + return function create[], W>( + dependencies: [...Dependencies], + callback: (deps: DepRecord<[...Dependencies]>) => W + ) { + console.log('Creating typed-function with dependencies:', dependencies) + // TODO: create a typed-function for real + return callback + } } diff --git a/tsconfig.json b/tsconfig.json index aae3a94..797c2d5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,6 @@ "compilerOptions": { "target": "ES2022", "rootDir": "./src", - "outDir": "./obj" + "outDir": "./build" } }