Files
traitify-ts/src/TraitExpression.ts
Julien Valverdé 463c8f1586
Some checks failed
continuous-integration/drone/push Build is failing
Refactoring
2024-02-05 00:07:07 +01:00

110 lines
2.8 KiB
TypeScript

import { Call, Fn, Pipe, Tuples } from "hotscript"
import { AbstractClass, Class, Opaque } from "type-fest"
import { AbstractTag, Trait, TraitApplierSuperTag } from "."
import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util"
export class TraitExpression<
Superclass extends AbstractClass<{}>,
OwnTraits extends Trait<any, any, any>[],
AllTraits extends Trait<any, any, any>[],
> {
constructor(
readonly superclass: Superclass,
readonly ownTraits: OwnTraits,
readonly allTraits: AllTraits,
) {}
get extends(): (
AbstractClass<
Pipe<[
InstanceType<Superclass>,
...Call<Tuples.Map<Trait.OwnImplInstanceFn>, OwnTraits>,
], [
ExtendFn,
SimplifyFn,
]>,
ConstructorParameters<Superclass>
> &
Pipe<[
Superclass,
...Call<Tuples.Map<Trait.OwnImplClassFn>, OwnTraits>,
], [
Tuples.Map<StaticMembersFn>,
ExtendFn,
SimplifyFn,
]>
) {
return this.allTraits.reduce(
(previous, trait) => trait.apply(previous),
this.superclass as Opaque<Superclass, TraitApplierSuperTag>,
) as any
}
subtrait<
SubtraitAbstract extends {},
SubtraitImplWithAbstract extends Class<{}>,
>(
abstract: (
abstract: Pipe<typeof this, [
]>
) => Opaque<SubtraitAbstract, AbstractTag>,
// impl: ()
) {
}
}
export namespace TraitExpression {
export class NullSuperclass {}
export type Superclass<T> = (
T extends TraitExpression<infer Superclass, any, any>
? Superclass
: never
)
export interface SuperclassFn extends Fn {
return: TraitExpression.Superclass<this["arg0"]>
}
export type OwnTraits<T> = (
T extends TraitExpression<any, infer OwnTraits, any>
? OwnTraits
: never
)
export interface OwnTraitsFn extends Fn {
return: TraitExpression.OwnTraits<this["arg0"]>
}
export type AllTraits<T> = (
T extends TraitExpression<any, any, infer AllTraits>
? AllTraits
: never
)
export interface AllTraitsFn extends Fn {
return: TraitExpression.AllTraits<this["arg0"]>
}
}
export type Implements<Exp extends TraitExpression<any, any, any>> = (
Exp extends TraitExpression<any, infer AllTraits, any>
? Pipe<AllTraits, [
Tuples.Map<Trait.OwnAbstractFn>,
ExtendFn,
SimplifyFn,
]>
: never
)
export const emptyTraitExpression = new TraitExpression(
TraitExpression.NullSuperclass,
[] as const,
[] as const,
)