0.1.11 #11
@@ -5,7 +5,137 @@ import { TraitExpression } from "./TraitExpression"
|
||||
import { Extendable, StaticMembers } from "./util"
|
||||
|
||||
|
||||
type SpreadSupertraits<Traits> = (
|
||||
export class TraitExpressionBuilder<
|
||||
Superclass extends AbstractClass<object>,
|
||||
const Traits extends Trait<any, any, any, any>[],
|
||||
> {
|
||||
declare ["constructor"]: typeof TraitExpressionBuilder
|
||||
|
||||
constructor(
|
||||
readonly expressionSuperclass: Superclass,
|
||||
readonly expressionTraits: Traits,
|
||||
) {}
|
||||
|
||||
|
||||
static spreadSupertraits<
|
||||
const T extends Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
traits: T
|
||||
) {
|
||||
return traits.flatMap(trait => [
|
||||
...trait.superExpression.traits,
|
||||
trait,
|
||||
]) as TraitExpressionBuilder.SpreadSupertraits<T>
|
||||
}
|
||||
|
||||
static uniqTraits<
|
||||
const T extends Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
traits: T
|
||||
) {
|
||||
return uniq(traits) as TraitExpressionBuilder.UniqTraits<T>
|
||||
}
|
||||
|
||||
|
||||
extends<
|
||||
Super extends AbstractClass<object>
|
||||
>(
|
||||
superclass: Super
|
||||
) {
|
||||
return new this.constructor(
|
||||
superclass,
|
||||
this.expressionTraits,
|
||||
)
|
||||
}
|
||||
|
||||
expresses<
|
||||
const T extends Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
...traits: T
|
||||
) {
|
||||
return new this.constructor(
|
||||
this.expressionSuperclass,
|
||||
|
||||
this.constructor.uniqTraits([
|
||||
...this.expressionTraits,
|
||||
...this.constructor.spreadSupertraits(traits),
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
expressesFirst<
|
||||
const T extends Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
...traits: T
|
||||
) {
|
||||
return new this.constructor(
|
||||
this.expressionSuperclass,
|
||||
|
||||
this.constructor.uniqTraits([
|
||||
...this.constructor.spreadSupertraits(traits),
|
||||
...this.expressionTraits,
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
build() {
|
||||
return new TraitExpression(
|
||||
this.expressionSuperclass,
|
||||
this.expressionTraits,
|
||||
) as TraitExpressionBuilder.BuildTraitExpression<Superclass, Traits>
|
||||
}
|
||||
|
||||
then<V>(fn: (expression: ReturnType<typeof this.build>) => V): V {
|
||||
return fn(this.build())
|
||||
}
|
||||
|
||||
buildAnyway() {
|
||||
return new TraitExpression(
|
||||
this.expressionSuperclass,
|
||||
this.expressionTraits,
|
||||
)
|
||||
}
|
||||
|
||||
thenAnyway<V>(fn: (expression: ReturnType<typeof this.buildAnyway>) => V): V {
|
||||
return fn(this.buildAnyway())
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TraitExpressionBuilder {
|
||||
export type SpreadSupertraits<Traits> = (
|
||||
Traits extends [
|
||||
infer El extends Trait<any, any, any, any>,
|
||||
...infer Rest,
|
||||
@@ -18,14 +148,14 @@ type SpreadSupertraits<Traits> = (
|
||||
: []
|
||||
)
|
||||
|
||||
type TraitsUniq<Traits> = (
|
||||
export type UniqTraits<Traits> = (
|
||||
Traits extends [
|
||||
...infer Rest,
|
||||
infer El extends Trait<any, any, any, any>,
|
||||
]
|
||||
? IsTraitInTupleFromRight<Rest, El> extends true
|
||||
? TraitsUniq<Rest>
|
||||
: [...TraitsUniq<Rest>, El]
|
||||
? UniqTraits<Rest>
|
||||
: [...UniqTraits<Rest>, El]
|
||||
: []
|
||||
)
|
||||
type IsTraitInTupleFromRight<Traits, T> = (
|
||||
@@ -36,8 +166,7 @@ type IsTraitInTupleFromRight<Traits, T> = (
|
||||
: false
|
||||
)
|
||||
|
||||
|
||||
type BuildTraitExpression<
|
||||
export type BuildTraitExpression<
|
||||
Superclass extends AbstractClass<object>,
|
||||
Traits extends Trait<any, any, any, any>[],
|
||||
> = (
|
||||
@@ -57,101 +186,7 @@ type BuildTraitExpression<
|
||||
? "Type conflict between the traits implementation static members and/or the superclass static members."
|
||||
: TraitExpression<Superclass, Traits>
|
||||
)
|
||||
|
||||
|
||||
export class TraitExpressionBuilder<
|
||||
Superclass extends AbstractClass<object>,
|
||||
const Traits extends Trait<any, any, any, any>[],
|
||||
> {
|
||||
constructor(
|
||||
readonly expressionSuperclass: Superclass,
|
||||
readonly expressionTraits: Traits,
|
||||
) {}
|
||||
|
||||
extends<
|
||||
Super extends AbstractClass<object>
|
||||
>(
|
||||
superclass: Super
|
||||
) {
|
||||
return new TraitExpressionBuilder(
|
||||
superclass,
|
||||
this.expressionTraits,
|
||||
)
|
||||
}
|
||||
|
||||
expresses<
|
||||
const T extends Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
...traits: T
|
||||
) {
|
||||
return new TraitExpressionBuilder(
|
||||
this.expressionSuperclass,
|
||||
|
||||
uniq([
|
||||
...this.expressionTraits,
|
||||
...traits.flatMap(trait => [
|
||||
...trait.superExpression.traits,
|
||||
trait,
|
||||
]),
|
||||
]) as TraitsUniq<[...Traits, ...SpreadSupertraits<T>]>,
|
||||
)
|
||||
}
|
||||
|
||||
expressesFirst<
|
||||
const T extends Trait<
|
||||
TraitExpression<
|
||||
typeof TraitExpression.NullSuperclass,
|
||||
Trait<any, any, any, any>[]
|
||||
>,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>[]
|
||||
>(
|
||||
...traits: T
|
||||
) {
|
||||
return new TraitExpressionBuilder(
|
||||
this.expressionSuperclass,
|
||||
|
||||
uniq([
|
||||
...traits.flatMap(trait => [
|
||||
...trait.superExpression.traits,
|
||||
trait,
|
||||
]),
|
||||
...this.expressionTraits,
|
||||
]) as TraitsUniq<[...SpreadSupertraits<T>, ...Traits]>,
|
||||
)
|
||||
}
|
||||
|
||||
build() {
|
||||
return new TraitExpression(
|
||||
this.expressionSuperclass,
|
||||
this.expressionTraits,
|
||||
) as BuildTraitExpression<Superclass, Traits>
|
||||
}
|
||||
|
||||
then<V>(fn: (expression: ReturnType<typeof this.build>) => V): V {
|
||||
return fn(this.build())
|
||||
}
|
||||
|
||||
buildAnyway() {
|
||||
return new TraitExpression(
|
||||
this.expressionSuperclass,
|
||||
this.expressionTraits,
|
||||
)
|
||||
}
|
||||
|
||||
thenAnyway<V>(fn: (expression: ReturnType<typeof this.buildAnyway>) => V): V {
|
||||
return fn(this.buildAnyway())
|
||||
}
|
||||
}
|
||||
|
||||
export const expression = new TraitExpressionBuilder(TraitExpression.NullSuperclass, [])
|
||||
|
||||
@@ -64,6 +64,7 @@ const exp = expression
|
||||
PrintsHelloOnNew,
|
||||
Identifiable<bigint>(),
|
||||
// Identifiable<number>(),
|
||||
// StatefulSubscription,
|
||||
ActiveStatefulSubscription,
|
||||
)
|
||||
.build()
|
||||
|
||||
Reference in New Issue
Block a user