137 lines
3.3 KiB
TypeScript
137 lines
3.3 KiB
TypeScript
import { AbstractClass, Class, Simplify } from "type-fest"
|
|
import { TraitExpression } from "./TraitExpression"
|
|
import { Extend, StaticMembers } from "./util"
|
|
|
|
|
|
export class Trait<
|
|
SuperExpression extends TraitExpression<
|
|
typeof TraitExpression.NullSuperclass,
|
|
readonly Trait<any, any, any, any>[]
|
|
>,
|
|
Abstract extends object,
|
|
StaticAbstract extends object,
|
|
ImplClass extends AbstractClass<object, []>,
|
|
> {
|
|
constructor(
|
|
readonly superExpression: SuperExpression,
|
|
readonly abstract: Abstract,
|
|
readonly staticAbstract: StaticAbstract,
|
|
readonly apply: (Super: AbstractClass<object>) => ImplClass,
|
|
) {}
|
|
}
|
|
|
|
export namespace Trait {
|
|
export type SuperExpression<T> = (
|
|
T extends Trait<infer SuperExpression, any, any, any>
|
|
? SuperExpression
|
|
: never
|
|
)
|
|
|
|
export type Supertraits<T> = (
|
|
TraitExpression.Traits<Trait.SuperExpression<T>>
|
|
)
|
|
|
|
export type Abstract<T> = (
|
|
T extends Trait<any, infer Abstract, any, any>
|
|
? Abstract
|
|
: never
|
|
)
|
|
|
|
export type StaticAbstract<T> = (
|
|
T extends Trait<any, any, infer StaticAbstract, any>
|
|
? StaticAbstract
|
|
: never
|
|
)
|
|
|
|
export type ImplClass<T> = (
|
|
T extends Trait<any, any, any, infer ImplClass>
|
|
? ImplClass
|
|
: never
|
|
)
|
|
|
|
export type ImplInstance<T> = (
|
|
InstanceType<Trait.ImplClass<T>>
|
|
)
|
|
|
|
export type ImplStaticMembers<T> = (
|
|
StaticMembers<Trait.ImplClass<T>>
|
|
)
|
|
|
|
export type Instance<T> = (
|
|
Extend<[
|
|
Trait.Abstract<T>,
|
|
Trait.ImplInstance<T>,
|
|
]>
|
|
)
|
|
|
|
export type Static<T> = (
|
|
Extend<[
|
|
Trait.StaticAbstract<T>,
|
|
Trait.ImplStaticMembers<T>,
|
|
]>
|
|
)
|
|
}
|
|
|
|
export namespace TraitTuple {
|
|
export type MapAbstract<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.Abstract<T[K]>
|
|
}
|
|
|
|
export type MapStaticAbstract<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.StaticAbstract<T[K]>
|
|
}
|
|
|
|
export type MapImplClass<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.ImplClass<T[K]>
|
|
}
|
|
|
|
export type MapImplInstance<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.ImplInstance<T[K]>
|
|
}
|
|
|
|
export type MapImplStaticMembers<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.ImplStaticMembers<T[K]>
|
|
}
|
|
|
|
export type MapInstance<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.Instance<T[K]>
|
|
}
|
|
|
|
export type MapStaticMembers<T> = {
|
|
[K in keyof T]: K extends keyof []
|
|
? T[K]
|
|
: Trait.Static<T[K]>
|
|
}
|
|
}
|
|
|
|
|
|
export type TraitClass<T extends Trait<any, any, any, any>> = (
|
|
AbstractClass<TraitInstance<T>, any[]> &
|
|
TraitStaticMembers<T>
|
|
)
|
|
|
|
export type TraitConcreteClass<T extends Trait<any, any, any, any>> = (
|
|
Class<TraitInstance<T>, any[]> &
|
|
TraitStaticMembers<T>
|
|
)
|
|
|
|
export type TraitInstance<T extends Trait<any, any, any, any>> = (
|
|
Simplify<Trait.Instance<T>>
|
|
)
|
|
|
|
export type TraitStaticMembers<T extends Trait<any, any, any, any>> = (
|
|
Simplify<Trait.Static<T>>
|
|
)
|