feat: make Type objects callable to prep for generics

This commit is contained in:
Glen Whitney 2025-04-17 20:18:34 -07:00
parent 70ce01d12b
commit 6de6515d3c
3 changed files with 16 additions and 3 deletions

View file

@ -1,13 +1,22 @@
export class Type {
export class Type extends Function {
constructor(f, options = {}) {
super()
this.test = f
this.from = options.from ?? {patterns: []} // mock empty Implementations
if ('zero' in options) this.zero = options.zero
if ('one' in options) this.one = options.one
if ('nan' in options) this.nan = options.nan
return new Proxy(this, {
apply: (target, thisForCall, args) => {
const callThrough = thisForCall ?? target
if (callThrough.specialize) return callThrough.specialize(...args)
throw new TypeError(`Type ${callThrough} is not generic`)
},
})
}
toString() {
return this.name || `[Type ${this.test}]`
return this.typeName || `[Type ${this.test}]`
}
}

View file

@ -84,7 +84,7 @@ export class TypeDispatcher {
throw new TypeError(`attempt to merge unusable type '${val}'`)
}
this.types[key] = val
val.name = key
val.typeName = key
continue
}

View file

@ -3,6 +3,7 @@ import {TypeDispatcher} from '../TypeDispatcher.js'
import * as booleans from '#boolean/all.js'
import * as generics from '#generic/all.js'
import * as numbers from '#number/all.js'
import {NumberT} from '#number/NumberT.js'
import {onType, ResolutionError} from "#core/helpers.js"
import {Any} from "#core/TypePatterns.js"
import {Returns, NotAType} from "#core/Type.js"
@ -68,4 +69,7 @@ describe('TypeDispatcher', () => {
const doomed = new TypeDispatcher()
assert.throws(() => doomed.merge({NaT: NotAType}), TypeError)
})
it('supports generic types', () => {
assert.throws(() => NumberT(0), TypeError)
})
})