Compare commits
No commits in common. "main" and "steptwo" have entirely different histories.
@ -7,8 +7,8 @@ Roadmap:
|
|||||||
1. Install over.ts and get an example of add with number and bigint implementations working with it. [DONE]
|
1. Install over.ts and get an example of add with number and bigint implementations working with it. [DONE]
|
||||||
2. Use the builder pattern to get add working with its implmentations defined incrementally before producing the final overload. [Didn't quite work the way we wnated, but maybe we can do an alternative later.]
|
2. Use the builder pattern to get add working with its implmentations defined incrementally before producing the final overload. [Didn't quite work the way we wnated, but maybe we can do an alternative later.]
|
||||||
3. Make a version of over.ts, call it util/overload.ts, that takes an array of implementations without redundant type annotation. [DONE]
|
3. Make a version of over.ts, call it util/overload.ts, that takes an array of implementations without redundant type annotation. [DONE]
|
||||||
4. Improve that version of overload with rtti to select the implementation without the implementations having to throw errors. [DONE]
|
4. Improve that version of overload with rtti to select the implementation without the implementations having to throw errors. [IN PROGRESS]
|
||||||
5. Use the builder pattern to get a single object with both an add and a negate method, with both defined incrementally, working. [DONE]
|
3. Use the builder pattern to get a single object with both an add and a negate method, with both defined incrementally, working.
|
||||||
4. Incorporate a subtract method that works on numbers and bigint by separate definitions but with dependencies on add and negate.
|
4. Incorporate a subtract method that works on numbers and bigint by separate definitions but with dependencies on add and negate.
|
||||||
5. Incorporate a subtract method that works with one generic implementation that works for both number and bigint with dependencies on add and negate.
|
5. Incorporate a subtract method that works with one generic implementation that works for both number and bigint with dependencies on add and negate.
|
||||||
5. Attempt to eliminate redundant specification of implementation signatures.
|
5. Attempt to eliminate redundant specification of implementation signatures.
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
main: 'index.js',
|
main: 'index.js',
|
||||||
scripts: {
|
scripts: {
|
||||||
test: 'echo "Error: no test specified" && exit 1',
|
test: 'echo "Error: no test specified" && exit 1',
|
||||||
build: 'ttsc -b',
|
|
||||||
},
|
},
|
||||||
keywords: [
|
keywords: [
|
||||||
'math',
|
'math',
|
||||||
@ -19,13 +18,6 @@
|
|||||||
license: 'Apache-2.0',
|
license: 'Apache-2.0',
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'over.ts': 'github:m93a/over.ts',
|
'over.ts': 'github:m93a/over.ts',
|
||||||
'reflect-metadata': '^0.1.13',
|
|
||||||
typescript: '^4.8.2',
|
typescript: '^4.8.2',
|
||||||
'typescript-rtti': '^0.8.2',
|
|
||||||
},
|
|
||||||
devDependencies: {
|
|
||||||
'@types/node': '^18.7.21',
|
|
||||||
'ts-node': '^10.9.1',
|
|
||||||
ttypescript: '^1.5.13',
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
186
pnpm-lock.yaml
186
pnpm-lock.yaml
@ -1,204 +1,20 @@
|
|||||||
lockfileVersion: 5.4
|
lockfileVersion: 5.4
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@types/node': ^18.7.21
|
|
||||||
over.ts: github:m93a/over.ts
|
over.ts: github:m93a/over.ts
|
||||||
reflect-metadata: ^0.1.13
|
|
||||||
ts-node: ^10.9.1
|
|
||||||
ttypescript: ^1.5.13
|
|
||||||
typescript: ^4.8.2
|
typescript: ^4.8.2
|
||||||
typescript-rtti: ^0.8.2
|
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
over.ts: github.com/m93a/over.ts/0fd6e18afd4ca5a23c9e09d1fcd6b7357b642247
|
over.ts: github.com/m93a/over.ts/0fd6e18afd4ca5a23c9e09d1fcd6b7357b642247
|
||||||
reflect-metadata: 0.1.13
|
|
||||||
typescript: 4.8.2
|
typescript: 4.8.2
|
||||||
typescript-rtti: 0.8.2_jbmzfhhdwyaatac7voo5jihpea
|
|
||||||
|
|
||||||
devDependencies:
|
|
||||||
'@types/node': 18.7.21
|
|
||||||
ts-node: 10.9.1_xxlomja3uhaizt5vuokco7nale
|
|
||||||
ttypescript: 1.5.13_s5ojjbx2isjkawqptqpitvy25q
|
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
/@cspotcode/source-map-support/0.8.1:
|
|
||||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
dependencies:
|
|
||||||
'@jridgewell/trace-mapping': 0.3.9
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@jridgewell/resolve-uri/3.1.0:
|
|
||||||
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
|
|
||||||
engines: {node: '>=6.0.0'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@jridgewell/sourcemap-codec/1.4.14:
|
|
||||||
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@jridgewell/trace-mapping/0.3.9:
|
|
||||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
|
||||||
dependencies:
|
|
||||||
'@jridgewell/resolve-uri': 3.1.0
|
|
||||||
'@jridgewell/sourcemap-codec': 1.4.14
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@tsconfig/node10/1.0.9:
|
|
||||||
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@tsconfig/node12/1.0.11:
|
|
||||||
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@tsconfig/node14/1.0.3:
|
|
||||||
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@tsconfig/node16/1.0.3:
|
|
||||||
resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/node/18.7.21:
|
|
||||||
resolution: {integrity: sha512-rLFzK5bhM0YPyCoTC8bolBjMk7bwnZ8qeZUBslBfjZQou2ssJdWslx9CZ8DGM+Dx7QXQiiTVZ/6QO6kwtHkZCA==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/acorn-walk/8.2.0:
|
|
||||||
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
|
|
||||||
engines: {node: '>=0.4.0'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/acorn/8.8.0:
|
|
||||||
resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
|
|
||||||
engines: {node: '>=0.4.0'}
|
|
||||||
hasBin: true
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/arg/4.1.3:
|
|
||||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/create-require/1.1.1:
|
|
||||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/diff/4.0.2:
|
|
||||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
|
||||||
engines: {node: '>=0.3.1'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/function-bind/1.1.1:
|
|
||||||
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/has/1.0.3:
|
|
||||||
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
|
|
||||||
engines: {node: '>= 0.4.0'}
|
|
||||||
dependencies:
|
|
||||||
function-bind: 1.1.1
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/is-core-module/2.10.0:
|
|
||||||
resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
|
|
||||||
dependencies:
|
|
||||||
has: 1.0.3
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/make-error/1.3.6:
|
|
||||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/path-parse/1.0.7:
|
|
||||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/reflect-metadata/0.1.13:
|
|
||||||
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/resolve/1.22.1:
|
|
||||||
resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
|
|
||||||
hasBin: true
|
|
||||||
dependencies:
|
|
||||||
is-core-module: 2.10.0
|
|
||||||
path-parse: 1.0.7
|
|
||||||
supports-preserve-symlinks-flag: 1.0.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/supports-preserve-symlinks-flag/1.0.0:
|
|
||||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
|
||||||
engines: {node: '>= 0.4'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/ts-node/10.9.1_xxlomja3uhaizt5vuokco7nale:
|
|
||||||
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
'@swc/core': '>=1.2.50'
|
|
||||||
'@swc/wasm': '>=1.2.50'
|
|
||||||
'@types/node': '*'
|
|
||||||
typescript: '>=2.7'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@swc/core':
|
|
||||||
optional: true
|
|
||||||
'@swc/wasm':
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@cspotcode/source-map-support': 0.8.1
|
|
||||||
'@tsconfig/node10': 1.0.9
|
|
||||||
'@tsconfig/node12': 1.0.11
|
|
||||||
'@tsconfig/node14': 1.0.3
|
|
||||||
'@tsconfig/node16': 1.0.3
|
|
||||||
'@types/node': 18.7.21
|
|
||||||
acorn: 8.8.0
|
|
||||||
acorn-walk: 8.2.0
|
|
||||||
arg: 4.1.3
|
|
||||||
create-require: 1.1.1
|
|
||||||
diff: 4.0.2
|
|
||||||
make-error: 1.3.6
|
|
||||||
typescript: 4.8.2
|
|
||||||
v8-compile-cache-lib: 3.0.1
|
|
||||||
yn: 3.1.1
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/ttypescript/1.5.13_s5ojjbx2isjkawqptqpitvy25q:
|
|
||||||
resolution: {integrity: sha512-KT/RBfGGlVJFqEI8cVvI3nMsmYcFvPSZh8bU0qX+pAwbi7/ABmYkzn7l/K8skw0xmYjVCoyaV6WLsBQxdadybQ==}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
ts-node: '>=8.0.2'
|
|
||||||
typescript: '>=3.2.2'
|
|
||||||
dependencies:
|
|
||||||
resolve: 1.22.1
|
|
||||||
ts-node: 10.9.1_xxlomja3uhaizt5vuokco7nale
|
|
||||||
typescript: 4.8.2
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/typescript-rtti/0.8.2_jbmzfhhdwyaatac7voo5jihpea:
|
|
||||||
resolution: {integrity: sha512-MZUHMX+Up1+7dYaAcOYSTxKc4PNLNXhuXYBkIzEKvQvxJ6xp7wcjTtiIYmB9+RJxRH5/9phZLqKTMpy20aQ4Aw==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
peerDependencies:
|
|
||||||
reflect-metadata: ^0.1.13
|
|
||||||
typescript: '4.6'
|
|
||||||
dependencies:
|
|
||||||
reflect-metadata: 0.1.13
|
|
||||||
typescript: 4.8.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/typescript/4.8.2:
|
/typescript/4.8.2:
|
||||||
resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==}
|
resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==}
|
||||||
engines: {node: '>=4.2.0'}
|
engines: {node: '>=4.2.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
dev: false
|
||||||
/v8-compile-cache-lib/3.0.1:
|
|
||||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/yn/3.1.1:
|
|
||||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
github.com/m93a/over.ts/0fd6e18afd4ca5a23c9e09d1fcd6b7357b642247:
|
github.com/m93a/over.ts/0fd6e18afd4ca5a23c9e09d1fcd6b7357b642247:
|
||||||
resolution: {tarball: https://codeload.github.com/m93a/over.ts/tar.gz/0fd6e18afd4ca5a23c9e09d1fcd6b7357b642247}
|
resolution: {tarball: https://codeload.github.com/m93a/over.ts/tar.gz/0fd6e18afd4ca5a23c9e09d1fcd6b7357b642247}
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import 'reflect-metadata'
|
|
||||||
import {reflect} from 'typescript-rtti'
|
|
||||||
import {merge, overloadValues} from '../util/overload.js'
|
|
||||||
|
|
||||||
const numImps = {
|
|
||||||
add: [(x: number, y: number) => x + y],
|
|
||||||
negate: [(x: number) => -x]
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const strImps = {
|
|
||||||
add: [(x: string, y: string) => x + ', ' + y],
|
|
||||||
negate: [(x: string) => 'NOT ' + x]
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const merger = merge(numImps)
|
|
||||||
const mathImps = merger.with(strImps).imps()
|
|
||||||
|
|
||||||
const math = overloadValues(mathImps)
|
|
||||||
|
|
||||||
console.log(math.add(1.5, 2.5))
|
|
||||||
console.log(math.add('One and a half', 'Two and a half'))
|
|
||||||
console.log(math.negate(3.5))
|
|
||||||
console.log(math.negate('Three and a half'))
|
|
||||||
|
|
||||||
//@ts-expect-error
|
|
||||||
console.log(math.add(1.5, 'Two and a half'))
|
|
@ -1,26 +0,0 @@
|
|||||||
import 'reflect-metadata'
|
|
||||||
import overload from '../util/overload.js'
|
|
||||||
|
|
||||||
const addImps = [
|
|
||||||
(x: number, y: number) => {
|
|
||||||
if (typeof x === 'number' && typeof y === 'number') return x + y
|
|
||||||
throw new TypeError('Can only add numbers')
|
|
||||||
},
|
|
||||||
(x: string, y: string) => {
|
|
||||||
if (typeof x === 'string' && typeof y === 'string') {
|
|
||||||
return 'Yay' + x + y
|
|
||||||
}
|
|
||||||
throw new TypeError('or strings')
|
|
||||||
},
|
|
||||||
(x: bigint, final?: string) => x.toString() + final
|
|
||||||
] as const
|
|
||||||
|
|
||||||
const adder = overload(addImps)
|
|
||||||
|
|
||||||
console.log(adder(1, 2))
|
|
||||||
console.log(adder('a', 'b'))
|
|
||||||
console.log(adder(2n))
|
|
||||||
|
|
||||||
// And make sure typescript complains on signatures not covered by an imp:
|
|
||||||
//@ts-expect-error
|
|
||||||
console.log(adder(2n, 4n))
|
|
@ -1,4 +1,4 @@
|
|||||||
import { useTypes } from '../../node_modules/over.ts/src/index.js';
|
import { useTypes } from 'over.ts/src/index.js';
|
||||||
|
|
||||||
const types = {
|
const types = {
|
||||||
number: (x: unknown): x is number => typeof x === 'number',
|
number: (x: unknown): x is number => typeof x === 'number',
|
||||||
|
@ -6,10 +6,7 @@ const adder = overload([
|
|||||||
throw new TypeError('Can only add numbers')
|
throw new TypeError('Can only add numbers')
|
||||||
},
|
},
|
||||||
(x: string, y: string) => 'Yay' + x + y
|
(x: string, y: string) => 'Yay' + x + y
|
||||||
] as const)
|
])
|
||||||
|
|
||||||
console.log(adder(1, 2))
|
console.log(adder(1, 2))
|
||||||
console.log(adder('a', 'b'))
|
console.log(adder('a', 'b'))
|
||||||
//@ts-expect-error
|
|
||||||
console.log(adder(3n, 4n))
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useTypes } from 'over.ts';
|
import { useTypes } from 'over.ts/src/index.js';
|
||||||
|
|
||||||
const types = {
|
const types = {
|
||||||
number: (x: unknown): x is number => typeof x === 'number',
|
number: (x: unknown): x is number => typeof x === 'number',
|
||||||
@ -69,8 +69,6 @@ addImps.addImp('number, number -> number', (a: number, b: number) => a+b) // ima
|
|||||||
const addAll = addImps.addImp('bigint, bigint -> bigint', (a: bigint, b: bigint) => a+b) // and this is in the `bigint` file
|
const addAll = addImps.addImp('bigint, bigint -> bigint', (a: bigint, b: bigint) => a+b) // and this is in the `bigint` file
|
||||||
const add = overload(addAll.finalize() as Omit<typeof addAll, 'finalize'|'addImp'>) // We wrap everything up elsewhere
|
const add = overload(addAll.finalize() as Omit<typeof addAll, 'finalize'|'addImp'>) // We wrap everything up elsewhere
|
||||||
|
|
||||||
// This should **NOT** be an error but sadly it is:
|
|
||||||
//@ts-expect-error
|
|
||||||
console.log('Sum of 5 and 7 is', add(5,7))
|
console.log('Sum of 5 and 7 is', add(5,7))
|
||||||
console.log('Sum of 5n and 7n is', add(5n, 7n))
|
console.log('Sum of 5n and 7n is', add(5n, 7n))
|
||||||
|
|
||||||
|
@ -1,117 +1,17 @@
|
|||||||
import {reflect, CallSite} from 'typescript-rtti'
|
|
||||||
|
|
||||||
type UnionToIntersection<U> =
|
type UnionToIntersection<U> =
|
||||||
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
|
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
|
||||||
? I
|
? I
|
||||||
: never;
|
: never;
|
||||||
|
|
||||||
export default function overload<T extends readonly [...any[]]>(
|
export default function overload<T extends readonly [...any[]]>(
|
||||||
imps: T, callSite?: CallSite): UnionToIntersection<T[number]> {
|
imps: T): UnionToIntersection<T[number]> {
|
||||||
const impTypes = reflect(callSite).parameters[0].elements
|
|
||||||
return <any>((...a: any[]) => {
|
return <any>((...a: any[]) => {
|
||||||
for (let i = 0; i < imps.length; ++i) {
|
for (let i = 0; i < imps.length; ++i) {
|
||||||
const paramTypes = imps[i].functionType.parameters
|
try {
|
||||||
|| impTypes[i].type.parameters
|
const val = imps[i](...a)
|
||||||
let match = true
|
return val
|
||||||
const haveArgs = a.length
|
} catch {
|
||||||
let onArg = 0
|
|
||||||
for (const param of paramTypes) {
|
|
||||||
if (param.isRest) {
|
|
||||||
// All the rest of the arguments must be of param's type
|
|
||||||
match = a.slice(onArg).every(
|
|
||||||
arg => param.type.matchesValue(arg))
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
if (onArg === haveArgs) {
|
|
||||||
// We've used all of the arguments, so better be optional
|
|
||||||
match = param.isOptional
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
// This argument must match this param's type and both are used
|
|
||||||
match = param.type.matchesValue(a[onArg])
|
|
||||||
onArg += 1
|
|
||||||
if (!match) break
|
|
||||||
}
|
|
||||||
// Make sure we used all the arguments
|
|
||||||
match &&= (onArg == haveArgs)
|
|
||||||
if (match) return imps[i](...a)
|
|
||||||
}
|
|
||||||
throw new TypeError(
|
|
||||||
`Actual arguments ${a} of type ${a.map(arg => typeof arg)} `
|
|
||||||
+ 'did not match any implementation')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type AVO = Record<string, readonly [...any[]]>
|
|
||||||
|
|
||||||
type MergeArrayValues<L extends AVO, R extends AVO> =
|
|
||||||
Pick<L, Exclude<keyof L, keyof R>>
|
|
||||||
& Pick<R, Exclude<keyof R, keyof L>>
|
|
||||||
& { [P in (keyof L & keyof R)]: [...L[P], ...R[P]] }
|
|
||||||
|
|
||||||
function mergeImps<T extends AVO, U extends AVO>(
|
|
||||||
impT: T, impU: U): MergeArrayValues<T, U> {
|
|
||||||
const dummy = Object.assign({}, impT, impU)
|
|
||||||
const result = {} as AVO
|
|
||||||
for (const key in dummy) {
|
|
||||||
if (key in impT) {
|
|
||||||
if (key in impU) {
|
|
||||||
const k = key as Extract<keyof T & keyof U, string>
|
|
||||||
result[k] = [...impT[k], ...impU[k]]
|
|
||||||
} else {
|
|
||||||
result[key] = impT[key]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result[key] = impU[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result as MergeArrayValues<T, U>
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImpMerger<T extends AVO> {
|
|
||||||
implementations: T
|
|
||||||
constructor(imps: T) {
|
|
||||||
this.implementations = imps
|
|
||||||
}
|
|
||||||
with<U extends AVO>(
|
|
||||||
moreImps: U, callSite?: CallSite): ImpMerger<MergeArrayValues<T,U>> {
|
|
||||||
const Utype = reflect(callSite).parameters[0]
|
|
||||||
// Annotate the implementations with their RTTI while we have it
|
|
||||||
for (const [key, imps] of Object.entries(moreImps)) {
|
|
||||||
if (!(imps[0].functionType)) {
|
|
||||||
const tuple = Utype.members.find(m => m.name === key)
|
|
||||||
for (let i = 0; i < imps.length; ++i) {
|
|
||||||
imps[i].functionType = tuple.type.elements[i].type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ImpMerger(mergeImps<T,U>(this.implementations, moreImps))
|
|
||||||
}
|
|
||||||
imps(): T {
|
|
||||||
return this.implementations
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function merge<T extends AVO>(impsObject: T, callSite?: CallSite) {
|
|
||||||
const Ttype = reflect(callSite).parameters[0]
|
|
||||||
// Annotate the implementations with their RTTI while we have it
|
|
||||||
for (const [key, imps] of Object.entries(impsObject)) {
|
|
||||||
if (!(imps[0].functionType)) {
|
|
||||||
const tuple = Ttype.members.find(m => m.name === key)
|
|
||||||
for (let i = 0; i < imps.length; ++i) {
|
|
||||||
imps[i].functionType = tuple.type.elements[i].type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ImpMerger(impsObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
type OverloadedValues<T extends AVO> = {
|
|
||||||
[P in keyof T]: UnionToIntersection<T[P][number]>}
|
|
||||||
|
|
||||||
function overloadValues<T extends AVO>(impObject: T) : OverloadedValues<T> {
|
|
||||||
return Object.fromEntries(Object.entries(impObject).map(
|
|
||||||
([k, v]) => [k, overload(v)])) as OverloadedValues<T>
|
|
||||||
}
|
|
||||||
|
|
||||||
export {merge, mergeImps, overloadValues}
|
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"baseUrl": ".",
|
"moduleResolution": "node",
|
||||||
"paths": {
|
"rootDir": "src",
|
||||||
"over.ts": ["node_modules/over.ts/src/index.js"],
|
|
||||||
"typescript-rtti": ["node_modules/typescript-rtti/dist/index.js"]
|
|
||||||
},
|
|
||||||
"plugins": [{ "transform": "typescript-rtti/dist/transformer" }],
|
|
||||||
"rootDir": ".",
|
|
||||||
"outDir": "obj"
|
"outDir": "obj"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"node_modules/over.ts/src/index.ts",
|
"src/steps/three.ts",
|
||||||
"src/steps/*.ts",
|
|
||||||
"src/util/*.ts"
|
"src/util/*.ts"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user