feat(overload): Use typescript-rtti to select implementations (#4)
Note that the changes to module resolution cause steps one and two no longer to run because node can't find the imports, although they still compile fine. Co-authored-by: Glen Whitney <glen@studioinfinity.org> Reviewed-on: #4
This commit is contained in:
parent
a2d019b021
commit
2f0a9936a3
9 changed files with 267 additions and 13 deletions
|
|
@ -1,17 +1,42 @@
|
|||
import {reflect, CallSite} from 'typescript-rtti'
|
||||
|
||||
type UnionToIntersection<U> =
|
||||
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
|
||||
? I
|
||||
: never;
|
||||
|
||||
export default function overload<T extends readonly [...any[]]>(
|
||||
imps: T): UnionToIntersection<T[number]> {
|
||||
imps: T, callSite?: CallSite): UnionToIntersection<T[number]> {
|
||||
const impTypes = reflect(callSite).parameters[0].elements
|
||||
return <any>((...a: any[]) => {
|
||||
for (let i = 0; i < imps.length; ++i) {
|
||||
try {
|
||||
const val = imps[i](...a)
|
||||
return val
|
||||
} catch {
|
||||
const paramTypes = impTypes[i].type.parameters
|
||||
let match = true
|
||||
const haveArgs = a.length
|
||||
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')
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue