This commit is contained in:
@@ -1,21 +1,100 @@
|
||||
import { Class } from "type-fest"
|
||||
import { AbstractClass, Class } from "type-fest"
|
||||
import { Trait } from "./Trait"
|
||||
import { TraitExpression } from "./TraitExpression"
|
||||
import { StaticMembers } from "./util"
|
||||
|
||||
|
||||
/*
|
||||
Ideas:
|
||||
- Make .abstract() and .staticAbstract() merge the declaration with the current Abstract or StaticAbstract
|
||||
*/
|
||||
class TraitBuilder<
|
||||
Supertraits extends TraitExpression<
|
||||
export type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super"
|
||||
|
||||
export type RemoveAbstractFromImplClass<
|
||||
ImplClassWithAbstract extends (
|
||||
Class<Abstract, []> &
|
||||
StaticAbstract &
|
||||
{ _tag: TraitApplierSuperTag }
|
||||
),
|
||||
Abstract extends object,
|
||||
StaticAbstract extends object,
|
||||
> = (
|
||||
Class<
|
||||
Omit<InstanceType<ImplClassWithAbstract>, keyof Abstract>,
|
||||
ConstructorParameters<ImplClassWithAbstract>
|
||||
> &
|
||||
Omit<StaticMembers<ImplClassWithAbstract>, keyof StaticAbstract | "_tag">
|
||||
)
|
||||
|
||||
|
||||
export class TraitBuilder<
|
||||
SuperExpression extends TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[],
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
Abstract extends {},
|
||||
StaticAbstract extends {},
|
||||
ImplClass extends Class<{}, []>,
|
||||
Abstract extends object,
|
||||
StaticAbstract extends object,
|
||||
ImplClass extends Class<object, []>,
|
||||
> {
|
||||
constructor(
|
||||
private readonly traitSuperExpression: SuperExpression,
|
||||
private readonly traitAbstract: Abstract,
|
||||
private readonly traitStaticAbstract: StaticAbstract,
|
||||
private readonly traitApply: (Super: AbstractClass<object>) => ImplClass,
|
||||
) {}
|
||||
|
||||
abstract<A extends Abstract>() {
|
||||
return new TraitBuilder(
|
||||
this.traitSuperExpression,
|
||||
{} as A,
|
||||
this.traitStaticAbstract,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
|
||||
staticAbstract<A extends StaticAbstract>() {
|
||||
return new TraitBuilder(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
{} as A,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
|
||||
implement<
|
||||
ImplClassWithAbstract extends (
|
||||
Class<Abstract, []> &
|
||||
StaticAbstract &
|
||||
{ _tag: TraitApplierSuperTag }
|
||||
)
|
||||
>(
|
||||
apply: (
|
||||
Super: (
|
||||
AbstractClass<Abstract> &
|
||||
StaticAbstract &
|
||||
{ _tag: TraitApplierSuperTag }
|
||||
)
|
||||
) => ImplClassWithAbstract
|
||||
) {
|
||||
return new Trait(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
this.traitStaticAbstract,
|
||||
apply as unknown as (Super: AbstractClass<object>) => RemoveAbstractFromImplClass<ImplClassWithAbstract, Abstract, StaticAbstract>,
|
||||
)
|
||||
}
|
||||
|
||||
build() {
|
||||
return new Trait(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
this.traitStaticAbstract,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const trait = new TraitBuilder(
|
||||
new TraitExpression(TraitExpression.NullSuperclass, [], []),
|
||||
{},
|
||||
{},
|
||||
Super => class extends Super {},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user