Files
traitify-ts/src/Trait.ts
Julien Valverdé bb1ae3b48f
All checks were successful
continuous-integration/drone/push Build is passing
Trait refactoring
2024-02-24 22:50:06 +01:00

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>>
)