typocomath/src/index.ts

100 lines
4.1 KiB
TypeScript

import 'reflect-metadata'
import {Dispatcher} from './core/Dispatcher.js'
import * as specifications from './all.js'
import {Complex} from './Complex/type.js'
import {absquare as absquare_complex} from './Complex/arithmetic.js'
import { CallSite, ReflectedObjectRef, reflect } from 'typescript-rtti'
import { square } from './generic/arithmetic.js'
// verify that typescript-rtti works (just as experiment)
const add = (a: number, b: number): number => a + b
console.log('reflect add')
console.log('parameterNames', reflect(add).parameterNames)
console.log('parameterTypes', reflect(add).parameterTypes.map(type => type.toString()))
console.log('returnType', reflect(add).returnType.toString())
console.log()
// output:
// reflect function add
// parameterNames [ 'a', 'b' ]
// parameterTypes [ 'class Number', 'class Number' ]
// returnType class Number
// try out a very simple case (just as experiment)
function createSquare(deps: {
multiply: (a: number, b: number) => number,
subtract: (a: number, b: number) => number
}) {
return (a: number) => deps.multiply(a, a)
}
console.log('reflect createSquare')
console.log('parameter names', reflect(createSquare).parameters.map(parameter => parameter.name))
// console.log('parameter[0]', (reflect(createSquare).parameters[0] as ReflectedFunctionParameter))
// @ts-ignore
console.log('parameterTypes[0]', (reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m)
console.log('parameterTypes[0].ref.m[0]',
// @ts-ignore
(reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m[0].n,
// @ts-ignore
(reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m[0]
)
console.log('parameterTypes[0].ref.m[0].t.m',
// @ts-ignore
(reflect(createSquare).parameterTypes[0] as ReflectedObjectRef)._ref.m[0].t.m
)
// @ts-ignore
// console.log('parameters[0]', reflect(createSquare).parameters[0])
// FIXME: where to find the information of the types of the dependencies multiply and subtract?
// Test whether we loose the type information when casting to a generic interface
// Conclusion: we keep the information, that is good.
console.log()
console.log('reflect createFunction')
type MathjsDependencies = Record<string, Function>
type MathjsCreateFunction = (deps: MathjsDependencies) => Function
const createFunction: MathjsCreateFunction = createSquare as MathjsCreateFunction
console.log('parameter names', reflect(createFunction).parameters.map(parameter => parameter.name))
// @ts-ignore
console.log('parameterTypes[0]', (reflect(createFunction).parameterTypes[0] as ReflectedObjectRef)._ref.m)
// TODO: more specific definition of Specifications
type Specifications = Record<string, Record<string, unknown>>
console.log()
console.log('CallSite')
function reflectSpecifications<T>(specifications: Specifications, callSite? : CallSite) {
console.log('specifications', reflect(callSite).parameters[0])
// @ts-ignore
console.log('specifications', reflect(callSite).parameters[0]._ref) // shows 'numbers', 'Complex, 'complex', 'generic'
// @ts-ignore
console.log('specifications', reflect(callSite).parameters[0]._ref.m
.find(item => item.n === 'generic').t.m) // shows 'square', 'unequal'
// @ts-ignore
console.log('specifications', reflect(callSite).parameters[0]._ref.m
.find(item => item.n === 'generic').t.m
.find(item => item.n === 'square').t.p) // [ { n: 'dep', t: [Function: t], b: undefined, v: null } ]
// @ts-ignore
// FIXME: now, we should be able to get the signature of the multiply dependency of the function square, but how?
}
reflectSpecifications<Specifications>(specifications);
// TODO: import all specifications (turned off for debugging purposes)
// export default new Dispatcher(Specifications)
const mockRealAdd = (a: number, b: number) => a+b
const mockComplexAbsquare = (z: Complex<number>) => z.re*z.re + z.im*z.im
const quatAbsquare = absquare_complex({
add: mockRealAdd,
absquare: mockComplexAbsquare
})
const myabs = quatAbsquare({re: {re: 0, im: 1}, im: {re:2, im: 3}})
const typeTest: typeof myabs = 7 // check myabs is just a number
console.log()
console.log('Result is', myabs)