Compare commits

..

No commits in common. "a4f5af3ea560b8029012f5e10be631aecc2286cc" and "722ee05a0a480aeb7ac9e59eeaacdfd164e3d66b" have entirely different histories.

6 changed files with 42 additions and 72 deletions

1
.gitignore vendored
View file

@ -3,7 +3,6 @@
# Typescript # Typescript
# emitted code # emitted code
obj obj
build
# ---> Node # ---> Node
# Logs # Logs

View file

@ -1,3 +1,3 @@
# typocomath # 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. 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.

View file

@ -4,7 +4,7 @@
description: 'A hopeful final typescipt-pragmatic mathjs proof-of-concept', description: 'A hopeful final typescipt-pragmatic mathjs proof-of-concept',
main: 'index.ts', main: 'index.ts',
scripts: { scripts: {
go: 'tsc && node build/infer.js' test: 'echo "Error: no test specified" && exit 1',
}, },
keywords: [ keywords: [
'math', 'math',

13
pnpm-lock.yaml generated
View file

@ -1,17 +1,14 @@
lockfileVersion: '6.0' lockfileVersion: 5.4
settings: specifiers:
autoInstallPeers: true typescript: ^4.9.3
excludeLinksFromLockfile: false
devDependencies: devDependencies:
typescript: typescript: 4.9.3
specifier: ^4.9.3
version: 4.9.3
packages: packages:
/typescript@4.9.3: /typescript/4.9.3:
resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true

View file

@ -5,79 +5,53 @@
* infer TypeScript interfaces from that using infer in template literal types. * infer TypeScript interfaces from that using infer in template literal types.
*/ */
type T = {} // TODO: how to do generics?
const create = createFactory<{ const create = createFactory<{
number: number number: number
bigint: bigint bigint: bigint
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:
const Multiply = 'multiply(number,number)=>number'
const Sqrt = 'sqrt(number)=>number'
const Zero = 'zero(number)=>number'
// TODO: get generics working
// TODO: how to pass config?
const createSquare = create(Sqrt, [Multiply, Zero],dep => // TODO: how to pass config?
x => dep.multiply(x, x) // 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 // 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
const zero = (a: number) => 0 const square = createSquare({ multiply })
const square = createSquare({ multiply, zero })
console.log('square', square(8)) // 64 console.log('square', square(8)) // 64
function createFactory<BaseTypes extends Record<string, unknown>>() { function createFactory<BaseTypes extends Record<string, unknown>>() {
type BaseTypeNames = string & keyof BaseTypes type K = string & keyof BaseTypes
type ResolveType<TypeName extends BaseTypeNames> = BaseTypes[TypeName]
type Value<K> = K type ResolveType<T extends K> = BaseTypes[T]
type ResolveArguments<S extends string> = S extends '' type ResolveArguments<S extends string> =
? [] S extends '' ? [] :
: S extends `${infer Arg extends BaseTypeNames},${infer Tail}` S extends `${infer T extends K}, ${infer U}`
? [ResolveType<Arg>, ...ResolveArguments<Tail>] ? [ResolveType<T>, ...ResolveArguments<U>]
: S extends `${infer Arg extends BaseTypeNames}` : S extends `${infer T extends K}` ? [ResolveType<T>]
? [ResolveType<Arg>] : never;
: never
type DependencyRecord<FnType> = type ResolveFunctionDef<T> =
FnType extends Value<infer K> T extends `${infer Name}(${infer Args}) : ${infer L extends K}`
? K extends `${infer Name}(${infer Args})=>${infer ReturnType extends BaseTypeNames}` ? (...args: ResolveArguments<Args>) => ResolveType<L>
? Record<Name, (...args: ResolveArguments<Args>) => ResolveType<ReturnType>> : never
: never
: never
type CreatedFunctionType<FnType> = return function create<T extends string, U extends string, V>(
FnType extends Value<infer K> dependencies: { [L in T]: U },
? K extends `${infer Name}(${infer Args})=>${infer ReturnType extends BaseTypeNames}` callback: (deps: { [L in T]: ResolveFunctionDef<U> }) => V
? (...args: ResolveArguments<Args>) => ResolveType<ReturnType> ) {
: never return callback
: never }
// inspired by: https://stackoverflow.com/questions/68391632/infer-type-from-array-literal
type DependenciesRecord<
Arr extends Array<Value<any>>,
Result extends Record<string, any> = {}
> = Arr extends []
? Result
: Arr extends [infer H, ...infer Tail]
? Tail extends Array<Value<any>>
? H extends Value<any>
? DependenciesRecord<Tail, Result & DependencyRecord<H>>
: never
: never
: never
return function create<K extends string, Dependencies extends Value<K>[], W extends Value<K>>(
signature: W,
dependencies: [...Dependencies],
callback: (deps: DependenciesRecord<[...Dependencies]>) => CreatedFunctionType<W>
) {
console.log('Creating typed-function with', { signature, dependencies })
// TODO: create a typed-function for real
return callback
}
} }

View file

@ -2,6 +2,6 @@
"compilerOptions": { "compilerOptions": {
"target": "ES2022", "target": "ES2022",
"rootDir": "./src", "rootDir": "./src",
"outDir": "./build" "outDir": "./obj"
} }
} }