refactor: Demonstrate macro generating a generic implementations interface
I swapped in the new macro in source files numbers/predicate.ts, Complex/arithmetic.ts, and Complex/predicate.ts. Note that you have to specify whether you are reflecting the generic or concrete implementations, which in some cases will mean two separate macro calls (as in Complex/predicate.ts). Also tried out the $$typeMetadata macro in Complex/all.ts; you can see the result by building and looking at build/Complex/all.js. It splits things up somewhat but we would still need to do a bunch of parsing, so probably not worth switching.
This commit is contained in:
parent
569079e908
commit
8dcf74c5d1
@ -1,6 +1,9 @@
|
||||
import * as Complex from './native.js'
|
||||
import * as complex from './arithmetic.js'
|
||||
import {$$typeMetadata} from 'ts-macros'
|
||||
|
||||
export { complex }
|
||||
|
||||
export {Complex}
|
||||
|
||||
const tryit = $$typeMetadata!<typeof complex>(true, true)
|
||||
|
@ -2,7 +2,7 @@ import {Complex} from './type.js'
|
||||
import type {
|
||||
Dependencies, Signature, Returns, RealType, AliasOf
|
||||
} from '../interfaces/type.js'
|
||||
import {$reflect} from '../interfaces/type.js'
|
||||
import {$reflectGen, GENERIC} from '../interfaces/type.js'
|
||||
|
||||
declare module "../interfaces/type" {
|
||||
interface Signatures<T> {
|
||||
@ -98,7 +98,11 @@ export const sqrt =
|
||||
return dep.divideReal(num, denom)
|
||||
}
|
||||
|
||||
$reflect!([
|
||||
export interface GenericImplementations<T> {
|
||||
kilroy: "was here"
|
||||
}
|
||||
|
||||
$reflectGen!(GENERIC, [
|
||||
add, addReal, unaryMinus, conj, subtract, multiply, absquare, divideReal,
|
||||
reciprocal, divide, sqrt
|
||||
])
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Complex} from './type.js'
|
||||
import type {Dependencies, Signature} from '../interfaces/type.js'
|
||||
import {$reflect} from '../interfaces/type.js'
|
||||
import {$reflectGen, GENERIC, CONCRETE} from '../interfaces/type.js'
|
||||
|
||||
export const isReal =
|
||||
<T>(dep: Dependencies<'add' | 'equal' | 'isReal', T>):
|
||||
@ -10,4 +10,5 @@ export const isReal =
|
||||
export const isSquare = (): Signature<'isSquare', Complex<unknown>> =>
|
||||
z => true // FIXME: not correct for Complex<bigint> once we get there
|
||||
|
||||
$reflect!([isReal, isSquare])
|
||||
$reflectGen!(GENERIC, [isReal])
|
||||
$reflectGen!(CONCRETE, [isSquare])
|
||||
|
@ -59,11 +59,11 @@ type BaseOperationSignature<
|
||||
Name extends BaseOperations<Obj>
|
||||
> = ValueIntersectionByKeyUnion<
|
||||
{[K in keyof Obj]:
|
||||
K extends Name
|
||||
? Obj[K]
|
||||
: Obj[K] extends Callable
|
||||
? ReturnType<Obj[K]>['aliasOf'] extends (Name | undefined)
|
||||
? Obj[K] : unknown
|
||||
Obj[K] extends Callable
|
||||
? K extends Name
|
||||
? ReturnType<Obj[K]>
|
||||
: ReturnType<Obj[K]>['aliasOf'] extends (Name | undefined)
|
||||
? ReturnType<Obj[K]> : unknown
|
||||
: unknown
|
||||
},
|
||||
keyof Obj>
|
||||
|
@ -77,7 +77,7 @@ type SignatureKey<T> = keyof Signatures<T>
|
||||
export type Signature<Name extends SignatureKey<T>, T> = Signatures<T>[Name]
|
||||
export type Returns<Name extends SignatureKey<T>, T> =
|
||||
ReturnType<Signatures<T>[Name]>
|
||||
type Deps<T> = T extends unknown ? { [K in keyof T]: T[K] } : never;
|
||||
export type Deps<T> = T extends unknown ? { [K in keyof T]: T[K] } : never;
|
||||
export type Dependencies<Name extends SignatureKey<T>, T> =
|
||||
Deps<{[K in Name]: Signature<K, T>}>
|
||||
|
||||
@ -88,3 +88,34 @@ export function $reflect<ImplTuple>(tup: ImplTuple) {
|
||||
+[[tup], <T>(elt: T) =>
|
||||
elt.reflectedType = $$typeToString!<T>(true, false, true)]
|
||||
}
|
||||
export function $genImps<ImplTuple>(tup: ImplTuple) {
|
||||
+[[tup], <U>(elt: U) => {
|
||||
export interface GenericImplementations<T> {
|
||||
[$$text!(elt)]: typeof elt
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
export function $genImpsT<ImplTuple>(tup: ImplTuple) {
|
||||
+[[tup], <U>(elt: U) => {
|
||||
export interface GenericImplementations<T> {
|
||||
[$$text!(elt)]: typeof elt<T>
|
||||
}
|
||||
}]
|
||||
}
|
||||
export const GENERIC = true
|
||||
export const CONCRETE = false
|
||||
export function $reflectGen<ImplTuple>(generic: boolean, tup: ImplTuple) {
|
||||
+[[tup], <T>(elt: T) => {
|
||||
elt.reflectedType = $$typeToString!<T>(true, false, true)
|
||||
if (generic) {
|
||||
export interface GenericImplementations<T> {
|
||||
[$$text!(elt)]: typeof elt<T>
|
||||
}
|
||||
} else {
|
||||
export interface GenericImplementations<T> {
|
||||
[$$text!(elt)]: typeof elt
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
@ -1,4 +1,9 @@
|
||||
import {GenericImplementations} from './predicate.js'
|
||||
import {$$typeToString} from 'ts-macros'
|
||||
export * from './type.js'
|
||||
export * from './arithmetic.js'
|
||||
export * from './predicate.js'
|
||||
export * from './relational.js'
|
||||
|
||||
const test: ReturnType<GenericImplementations<unknown>['isReal']> =
|
||||
(a: number) => true // = "oops" would fail as desired.
|
||||
|
@ -1,7 +1,11 @@
|
||||
import type {Signature} from '../interfaces/type.js'
|
||||
import {$reflect} from '../interfaces/type.js'
|
||||
|
||||
import {$reflectGen, CONCRETE} from '../interfaces/type.js'
|
||||
import {$$typeToString} from 'ts-macros'
|
||||
export const isReal = (): Signature<'isReal', number> => (a) => true
|
||||
export const isSquare = (): Signature<'isSquare', number> => (a) => a >= 0
|
||||
|
||||
$reflect!([isReal, isSquare])
|
||||
export interface GenericImplementations<T> {
|
||||
kilroy: "was here"
|
||||
}
|
||||
|
||||
$reflectGen!(CONCRETE, [isReal, isSquare])
|
||||
|
Loading…
Reference in New Issue
Block a user