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 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> console.log() console.log('CallSite') function reflectSpecifications(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); // 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) => 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)