typocomath/src/generic/arithmetic.ts

33 lines
1.4 KiB
TypeScript

import type {Dependencies, Signature} from '../interfaces/type.js'
// This stuff would really go in interfaces/type.js or someplace like that
type Annotate<U> = U & {dependencies?: Record<string, string>, signature?: string}
function genericImplementation<Deps extends Record<string, string>, Sig extends string>(
deps: Deps, sig: Sig, impl: <T>(dep: Dependencies<keyof Deps, T>) => Signature<Sig, T>
) {
const rimpl: Annotate<typeof impl> = impl
rimpl.dependencies = deps
rimpl.signature = sig
return rimpl
}
// and of course it would need to be generalized somewhat from the above
// --------------
// Then here for the implementation we would have:
export const square = genericImplementation(
{multiply: 'T'}, 'square', <T>(dep) => z => dep.multiply(z, z)
)
// Note this was previously
// export const square =
// <T>(dep: Dependencies<'multiply', T>): Signature<'square', T> =>
// z => dep.multiply(z, z)
// but then we couldn't get at the dependencies or the signature at runtime. So the point of
// genericImplementation is that it takes literal values for the dependencies and signature,
// from which it deduces the types of the actual dependencies of the implementation and the
// the implementation itself, and then it copies those literal values onto properties of the
// implementation, where they can be accessed at runtime as illustreated in ../index.ts