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 './native.js'
|
||||||
import * as complex from './arithmetic.js'
|
import * as complex from './arithmetic.js'
|
||||||
|
import {$$typeMetadata} from 'ts-macros'
|
||||||
|
|
||||||
export { complex }
|
export { complex }
|
||||||
|
|
||||||
export {Complex}
|
export {Complex}
|
||||||
|
|
||||||
|
const tryit = $$typeMetadata!<typeof complex>(true, true)
|
||||||
|
@ -2,7 +2,7 @@ import {Complex} from './type.js'
|
|||||||
import type {
|
import type {
|
||||||
Dependencies, Signature, Returns, RealType, AliasOf
|
Dependencies, Signature, Returns, RealType, AliasOf
|
||||||
} from '../interfaces/type.js'
|
} from '../interfaces/type.js'
|
||||||
import {$reflect} from '../interfaces/type.js'
|
import {$reflectGen, GENERIC} from '../interfaces/type.js'
|
||||||
|
|
||||||
declare module "../interfaces/type" {
|
declare module "../interfaces/type" {
|
||||||
interface Signatures<T> {
|
interface Signatures<T> {
|
||||||
@ -98,7 +98,11 @@ export const sqrt =
|
|||||||
return dep.divideReal(num, denom)
|
return dep.divideReal(num, denom)
|
||||||
}
|
}
|
||||||
|
|
||||||
$reflect!([
|
export interface GenericImplementations<T> {
|
||||||
|
kilroy: "was here"
|
||||||
|
}
|
||||||
|
|
||||||
|
$reflectGen!(GENERIC, [
|
||||||
add, addReal, unaryMinus, conj, subtract, multiply, absquare, divideReal,
|
add, addReal, unaryMinus, conj, subtract, multiply, absquare, divideReal,
|
||||||
reciprocal, divide, sqrt
|
reciprocal, divide, sqrt
|
||||||
])
|
])
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {Complex} from './type.js'
|
import {Complex} from './type.js'
|
||||||
import type {Dependencies, Signature} from '../interfaces/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 =
|
export const isReal =
|
||||||
<T>(dep: Dependencies<'add' | 'equal' | 'isReal', T>):
|
<T>(dep: Dependencies<'add' | 'equal' | 'isReal', T>):
|
||||||
@ -10,4 +10,5 @@ export const isReal =
|
|||||||
export const isSquare = (): Signature<'isSquare', Complex<unknown>> =>
|
export const isSquare = (): Signature<'isSquare', Complex<unknown>> =>
|
||||||
z => true // FIXME: not correct for Complex<bigint> once we get there
|
z => true // FIXME: not correct for Complex<bigint> once we get there
|
||||||
|
|
||||||
$reflect!([isReal, isSquare])
|
$reflectGen!(GENERIC, [isReal])
|
||||||
|
$reflectGen!(CONCRETE, [isSquare])
|
||||||
|
@ -59,12 +59,12 @@ type BaseOperationSignature<
|
|||||||
Name extends BaseOperations<Obj>
|
Name extends BaseOperations<Obj>
|
||||||
> = ValueIntersectionByKeyUnion<
|
> = ValueIntersectionByKeyUnion<
|
||||||
{[K in keyof Obj]:
|
{[K in keyof Obj]:
|
||||||
K extends Name
|
Obj[K] extends Callable
|
||||||
? Obj[K]
|
? K extends Name
|
||||||
: Obj[K] extends Callable
|
? ReturnType<Obj[K]>
|
||||||
? ReturnType<Obj[K]>['aliasOf'] extends (Name | undefined)
|
: ReturnType<Obj[K]>['aliasOf'] extends (Name | undefined)
|
||||||
? Obj[K] : unknown
|
? ReturnType<Obj[K]> : unknown
|
||||||
: unknown
|
: unknown
|
||||||
},
|
},
|
||||||
keyof Obj>
|
keyof Obj>
|
||||||
// Get the type of a given operation in a SpecificationsGroup
|
// Get the type of a given operation in a SpecificationsGroup
|
||||||
|
@ -77,7 +77,7 @@ type SignatureKey<T> = keyof Signatures<T>
|
|||||||
export type Signature<Name extends SignatureKey<T>, T> = Signatures<T>[Name]
|
export type Signature<Name extends SignatureKey<T>, T> = Signatures<T>[Name]
|
||||||
export type Returns<Name extends SignatureKey<T>, T> =
|
export type Returns<Name extends SignatureKey<T>, T> =
|
||||||
ReturnType<Signatures<T>[Name]>
|
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> =
|
export type Dependencies<Name extends SignatureKey<T>, T> =
|
||||||
Deps<{[K in Name]: Signature<K, T>}>
|
Deps<{[K in Name]: Signature<K, T>}>
|
||||||
|
|
||||||
@ -88,3 +88,34 @@ export function $reflect<ImplTuple>(tup: ImplTuple) {
|
|||||||
+[[tup], <T>(elt: T) =>
|
+[[tup], <T>(elt: T) =>
|
||||||
elt.reflectedType = $$typeToString!<T>(true, false, true)]
|
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 './type.js'
|
||||||
export * from './arithmetic.js'
|
export * from './arithmetic.js'
|
||||||
export * from './predicate.js'
|
export * from './predicate.js'
|
||||||
export * from './relational.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 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 isReal = (): Signature<'isReal', number> => (a) => true
|
||||||
export const isSquare = (): Signature<'isSquare', number> => (a) => a >= 0
|
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