This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import { Call, Pipe, Tuples } from "hotscript"
|
||||
import { Call, Fn, Pipe, Tuples } from "hotscript"
|
||||
import { AbstractClass, Class, Opaque } from "type-fest"
|
||||
import { AbstractTag, Trait, TraitApplierSuperTag, TraitOwnAbstractFn, TraitOwnImplClassFn, TraitOwnImplInstanceFn } from "."
|
||||
import { AbstractTag, Trait, TraitAbstractFn, TraitApplierSuperTag, TraitOwnAbstractFn, TraitOwnImplClassFn, TraitOwnImplInstanceFn, TraitSupertraitsFn } from "."
|
||||
import { ExtendFn, ExtendableFn, SimplifyFn, StaticMembersFn } from "./util"
|
||||
|
||||
|
||||
export class TraitExpressionNullSuperclass {}
|
||||
|
||||
export class TraitExpression<
|
||||
Super extends AbstractClass<{}>,
|
||||
Traits extends Trait<any, any, any>[],
|
||||
@@ -58,6 +60,46 @@ export class TraitExpression<
|
||||
}
|
||||
}
|
||||
|
||||
export const emptyTraitExpression = new TraitExpression(TraitExpressionNullSuperclass, [] as const)
|
||||
|
||||
interface PrependTraitSupertraitsFn extends Fn {
|
||||
return: [
|
||||
...Call<TraitSupertraitsFn, this["arg0"]>,
|
||||
this["arg0"],
|
||||
]
|
||||
}
|
||||
export interface TraitExpressionTraitsFn extends Fn {
|
||||
return: this["arg0"] extends TraitExpression<any, infer Traits>
|
||||
? Call<Tuples.FlatMap<PrependTraitSupertraitsFn>, Traits>
|
||||
: never
|
||||
}
|
||||
|
||||
export interface TraitExpressionAbstractFn extends Fn {
|
||||
return: this["arg0"] extends TraitExpression<any, infer Traits>
|
||||
? Pipe<Traits, [
|
||||
TraitAbstractFn,
|
||||
ExtendFn,
|
||||
]>
|
||||
: never
|
||||
}
|
||||
|
||||
export interface TraitExpressionInstanceFn extends Fn {
|
||||
return: this["arg0"] extends TraitExpression<infer Super, infer Traits>
|
||||
? Pipe<Traits, [
|
||||
TraitAbstractFn,
|
||||
ExtendFn,
|
||||
]>
|
||||
: never
|
||||
}
|
||||
|
||||
export interface TraitExpressionStaticFn extends Fn {
|
||||
return: this["arg0"] extends TraitExpression<infer Super, infer Traits>
|
||||
? Pipe<Traits, [
|
||||
TraitAbstractFn,
|
||||
ExtendFn,
|
||||
]>
|
||||
: never
|
||||
}
|
||||
|
||||
|
||||
export type Implements<Exp extends TraitExpression<any, any>> = (
|
||||
@@ -158,8 +200,4 @@ type GetTraitExpression<
|
||||
)
|
||||
|
||||
|
||||
export class NullTraitExpressionSuperclass {}
|
||||
|
||||
export const expression = new TraitExpressionBuilder(
|
||||
new TraitExpression(NullTraitExpressionSuperclass, [] as const)
|
||||
)
|
||||
export const expression = new TraitExpressionBuilder(emptyTraitExpression)
|
||||
|
||||
16
src/tests.ts
16
src/tests.ts
@@ -1,4 +1,4 @@
|
||||
import { Implements, TraitAbstractMembers, abstract, expression, trait } from "."
|
||||
import { Implements, abstract, expression, trait } from "."
|
||||
|
||||
|
||||
const PrintsHelloOnNew = trait(
|
||||
@@ -32,14 +32,14 @@ const StatefulSubscription = trait(
|
||||
Super => class StatefulSubscription extends Super {},
|
||||
)
|
||||
|
||||
interface ActiveStatefulSubscriptionAbstractMembers extends TraitAbstractMembers<typeof StatefulSubscription> {
|
||||
readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date }
|
||||
}
|
||||
// interface ActiveStatefulSubscriptionAbstractMembers extends TraitAbstractMembers<typeof StatefulSubscription> {
|
||||
// readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date }
|
||||
// }
|
||||
|
||||
const ActiveStatefulSubscription = trait(
|
||||
abstract<ActiveStatefulSubscriptionAbstractMembers>(),
|
||||
Super => class ActiveStatefulSubscription extends Super {},
|
||||
)
|
||||
// const ActiveStatefulSubscription = trait(
|
||||
// abstract<ActiveStatefulSubscriptionAbstractMembers>(),
|
||||
// Super => class ActiveStatefulSubscription extends Super {},
|
||||
// )
|
||||
|
||||
|
||||
class TestSuperclass {
|
||||
|
||||
26
src/trait.ts
26
src/trait.ts
@@ -1,7 +1,7 @@
|
||||
import { Call, Fn } from "hotscript"
|
||||
import { AbstractClass, Class, Opaque } from "type-fest"
|
||||
import { AbstractTag, NullTraitExpressionSuperclass, TraitExpression } from "."
|
||||
import { StaticMembers } from "./util"
|
||||
import { AbstractTag, TraitExpression, TraitExpressionAbstractFn, TraitExpressionNullSuperclass, TraitExpressionTraitsFn, emptyTraitExpression } from "."
|
||||
import { ExtendFn, StaticMembers } from "./util"
|
||||
|
||||
|
||||
type AddAbstractToImplClass<
|
||||
@@ -28,7 +28,7 @@ type RemoveAbstractFromImplClass<
|
||||
|
||||
|
||||
export class Trait<
|
||||
Super extends TraitExpression<typeof NullTraitExpressionSuperclass, any>[],
|
||||
Super extends TraitExpression<typeof TraitExpressionNullSuperclass, any>,
|
||||
Abstract extends {},
|
||||
ImplClass extends Class<{}, []>,
|
||||
> {
|
||||
@@ -54,7 +54,7 @@ export interface TraitOwnImplClassFn extends Fn {
|
||||
export type TraitOwnImplClass<T> = Call<TraitOwnImplClassFn, T>
|
||||
|
||||
export interface TraitOwnImplInstanceFn extends Fn {
|
||||
return: this["arg0"] extends Trait<any, infer Abstract, infer ImplClass>
|
||||
return: this["arg0"] extends Trait<any, any, infer ImplClass>
|
||||
? InstanceType<ImplClass>
|
||||
: never
|
||||
}
|
||||
@@ -77,6 +77,22 @@ export interface TraitOwnInstanceFn extends Fn {
|
||||
export type TraitOwnInstance<T> = Call<TraitOwnInstanceFn, T>
|
||||
|
||||
|
||||
export interface TraitSupertraitsFn extends Fn {
|
||||
return: this["arg0"] extends Trait<infer Super, any, any>
|
||||
? Call<TraitExpressionTraitsFn, Super>
|
||||
: never
|
||||
}
|
||||
|
||||
export interface TraitAbstractFn extends Fn {
|
||||
return: this["arg0"] extends Trait<infer Super, infer Abstract, any>
|
||||
? Call<ExtendFn, [
|
||||
...Call<TraitExpressionAbstractFn, Super>,
|
||||
Abstract,
|
||||
]>
|
||||
: never
|
||||
}
|
||||
|
||||
|
||||
export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper"
|
||||
|
||||
export function trait<
|
||||
@@ -89,7 +105,7 @@ export function trait<
|
||||
),
|
||||
) {
|
||||
return new Trait(
|
||||
[] as const,
|
||||
emptyTraitExpression,
|
||||
abstract as Abstract,
|
||||
apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass<ImplClassWithAbstract, Abstract>,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user