TraitBuilder refactoring
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -6,7 +6,91 @@ import { Extend, StaticMembers } from "./util"
|
||||
|
||||
declare const implSuperSymbol: unique symbol
|
||||
|
||||
type ImplSuper<This> = (
|
||||
|
||||
export class TraitBuilder<
|
||||
SuperExpression extends TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
Abstract extends object,
|
||||
StaticAbstract extends object,
|
||||
ImplClass extends AbstractClass<object, []>,
|
||||
> {
|
||||
declare ["constructor"]: typeof TraitBuilder
|
||||
|
||||
constructor(
|
||||
readonly traitSuperExpression: SuperExpression,
|
||||
readonly traitAbstract: Abstract,
|
||||
readonly traitStaticAbstract: StaticAbstract,
|
||||
readonly traitApply: (Super: AbstractClass<object>) => ImplClass,
|
||||
) {}
|
||||
|
||||
|
||||
abstract<A extends Abstract>(
|
||||
_: (Super: AbstractClass<Abstract>) => AbstractClass<A, []>
|
||||
) {
|
||||
return new this.constructor(
|
||||
this.traitSuperExpression,
|
||||
{} as Simplify<A>,
|
||||
this.traitStaticAbstract,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
|
||||
staticAbstract<A extends StaticAbstract>(
|
||||
_: (Super: AbstractClass<StaticAbstract>) => AbstractClass<A, []>
|
||||
) {
|
||||
return new this.constructor(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
{} as Simplify<A>,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
|
||||
implement<
|
||||
ImplClassWithAbstract extends TraitBuilder.ImplSuper<typeof this> // TODO: find a way to set the constraint to concrete classes while keeping the Super arg as an abstract class
|
||||
>(
|
||||
apply: (Super: TraitBuilder.ImplSuper<typeof this>) => ImplClassWithAbstract
|
||||
) {
|
||||
return new this.constructor(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
this.traitStaticAbstract,
|
||||
|
||||
apply as unknown as (Super: AbstractClass<object>) => (
|
||||
AbstractClass<
|
||||
Simplify<
|
||||
Omit<
|
||||
InstanceType<ImplClassWithAbstract>,
|
||||
keyof Abstract
|
||||
>
|
||||
>
|
||||
> &
|
||||
|
||||
Simplify<
|
||||
Omit<
|
||||
StaticMembers<ImplClassWithAbstract>,
|
||||
keyof StaticAbstract | typeof implSuperSymbol
|
||||
>
|
||||
>
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
build() {
|
||||
return new Trait(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
this.traitStaticAbstract,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TraitBuilder {
|
||||
export type ImplSuper<This> = (
|
||||
This extends TraitBuilder<
|
||||
any,
|
||||
infer Abstract,
|
||||
@@ -33,85 +117,8 @@ type ImplSuper<This> = (
|
||||
)
|
||||
: never
|
||||
)
|
||||
|
||||
|
||||
export class TraitBuilder<
|
||||
SuperExpression extends TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
Abstract extends object,
|
||||
StaticAbstract extends object,
|
||||
ImplClass extends AbstractClass<object, []>,
|
||||
> {
|
||||
constructor(
|
||||
readonly traitSuperExpression: SuperExpression,
|
||||
readonly traitAbstract: Abstract,
|
||||
readonly traitStaticAbstract: StaticAbstract,
|
||||
readonly traitApply: (Super: AbstractClass<object>) => ImplClass,
|
||||
) {}
|
||||
|
||||
abstract<A extends Abstract>(
|
||||
_: (Super: AbstractClass<Abstract>) => AbstractClass<A, []>
|
||||
) {
|
||||
return new TraitBuilder(
|
||||
this.traitSuperExpression,
|
||||
{} as Simplify<A>,
|
||||
this.traitStaticAbstract,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
|
||||
staticAbstract<A extends StaticAbstract>(
|
||||
_: (Super: AbstractClass<StaticAbstract>) => AbstractClass<A, []>
|
||||
) {
|
||||
return new TraitBuilder(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
{} as Simplify<A>,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
|
||||
implement<
|
||||
ImplClassWithAbstract extends ImplSuper<typeof this> // TODO: find a way to set the constraint to concrete classes while keeping the Super arg as an abstract class
|
||||
>(
|
||||
apply: (Super: ImplSuper<typeof this>) => ImplClassWithAbstract
|
||||
) {
|
||||
return new TraitBuilder(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
this.traitStaticAbstract,
|
||||
|
||||
apply as unknown as (Super: AbstractClass<object>) => (
|
||||
AbstractClass<
|
||||
Simplify<
|
||||
Omit<
|
||||
InstanceType<ImplClassWithAbstract>,
|
||||
keyof Abstract
|
||||
>
|
||||
>
|
||||
> &
|
||||
|
||||
Simplify<
|
||||
Omit<
|
||||
StaticMembers<ImplClassWithAbstract>,
|
||||
keyof StaticAbstract | typeof implSuperSymbol
|
||||
>
|
||||
>
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
build() {
|
||||
return new Trait(
|
||||
this.traitSuperExpression,
|
||||
this.traitAbstract,
|
||||
this.traitStaticAbstract,
|
||||
this.traitApply,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const trait = new TraitBuilder(
|
||||
new TraitExpression(TraitExpression.NullSuperclass, []),
|
||||
|
||||
Reference in New Issue
Block a user