feat: add example of specifying dependencies and signature with runtime vals
This commit is contained in:
parent
cc1e66c054
commit
ed2ae1b006
@ -18,6 +18,8 @@
|
|||||||
url: 'https://code.studioinfinity.org/glen/typocomath.git',
|
url: 'https://code.studioinfinity.org/glen/typocomath.git',
|
||||||
},
|
},
|
||||||
devDependencies: {
|
devDependencies: {
|
||||||
|
'@types/node': '^20.5.0',
|
||||||
|
'source-map': '^0.7.4',
|
||||||
typescript: '^4.9.3',
|
typescript: '^4.9.3',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,32 @@
|
|||||||
lockfileVersion: 5.4
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
specifiers:
|
settings:
|
||||||
typescript: ^4.9.3
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
typescript: 4.9.3
|
'@types/node':
|
||||||
|
specifier: ^20.5.0
|
||||||
|
version: 20.5.0
|
||||||
|
source-map:
|
||||||
|
specifier: ^0.7.4
|
||||||
|
version: 0.7.4
|
||||||
|
typescript:
|
||||||
|
specifier: ^4.9.3
|
||||||
|
version: 4.9.3
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
/typescript/4.9.3:
|
/@types/node@20.5.0:
|
||||||
|
resolution: {integrity: sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/source-map@0.7.4:
|
||||||
|
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/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
|
||||||
|
@ -1,5 +1,32 @@
|
|||||||
import type {Dependencies, Signature} from '../interfaces/type.js'
|
import type {Dependencies, Signature} from '../interfaces/type.js'
|
||||||
|
|
||||||
export const square =
|
// This stuff would really go in interfaces/type.js or someplace like that
|
||||||
<T>(dep: Dependencies<'multiply', T>): Signature<'square', T> =>
|
type Annotate<U> = U & {dependencies?: Record<string, string>, signature?: string}
|
||||||
z => dep.multiply(z, z)
|
|
||||||
|
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
|
||||||
|
11
src/index.ts
11
src/index.ts
@ -18,3 +18,14 @@ const myabs = quatAbsquare({re: {re: 0, im: 1}, im: {re:2, im: 3}})
|
|||||||
const typeTest: typeof myabs = 7 // check myabs is just a number
|
const typeTest: typeof myabs = 7 // check myabs is just a number
|
||||||
|
|
||||||
console.log('Result is', myabs)
|
console.log('Result is', myabs)
|
||||||
|
|
||||||
|
console.log('Dependencies of square are', Specifications.generic.square.dependencies)
|
||||||
|
console.log('Signature of square is', Specifications.generic.square.signature)
|
||||||
|
|
||||||
|
const realSquare = Specifications.generic.square<number>({multiply: (a,b) => a*b})
|
||||||
|
console.log('Square of 2.5 is', realSquare(2.5))
|
||||||
|
|
||||||
|
// and note the following fail with a type error as desired:
|
||||||
|
// const fakeSquare = Specifications.generic.square<number>({multiply: (a,b,c) => a*b*c})
|
||||||
|
// const stringSquare = Specifications.generic.square<string>({multiply: (a,b) => a*b})
|
||||||
|
// console.log('Square of three is', stringSquare('three'))
|
||||||
|
@ -68,8 +68,8 @@ export interface Signatures<T> {
|
|||||||
|
|
||||||
type SignatureKey<T> = keyof Signatures<T>
|
type SignatureKey<T> = keyof Signatures<T>
|
||||||
|
|
||||||
export type Signature<Name extends SignatureKey<T>, T> = Signatures<T>[Name]
|
export type Signature<Name, T> = Signatures<T>[Name & SignatureKey<T>]
|
||||||
export type Returns<Name extends SignatureKey<T>, T> = ReturnType<Signatures<T>[Name]>
|
export type Returns<Name extends SignatureKey<T>, T> = ReturnType<Signatures<T>[Name]>
|
||||||
export type Dependencies<Name extends SignatureKey<T>, T> = {[K in Name]: Signature<K, T>}
|
export type Dependencies<Name, T> = {[K in Name & SignatureKey<T>]: Signature<K, T>}
|
||||||
|
|
||||||
export type AliasOf<Name extends string, T> = T & {aliasOf?: Name}
|
export type AliasOf<Name extends string, T> = T & {aliasOf?: Name}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"outDir": "./obj"
|
"outDir": "./obj",
|
||||||
|
"moduleResolution": "nodenext"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user