diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index a069f95..c0ea010 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -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[], @@ -58,6 +60,46 @@ export class TraitExpression< } } +export const emptyTraitExpression = new TraitExpression(TraitExpressionNullSuperclass, [] as const) + +interface PrependTraitSupertraitsFn extends Fn { + return: [ + ...Call, + this["arg0"], + ] +} +export interface TraitExpressionTraitsFn extends Fn { + return: this["arg0"] extends TraitExpression + ? Call, Traits> + : never +} + +export interface TraitExpressionAbstractFn extends Fn { + return: this["arg0"] extends TraitExpression + ? Pipe + : never +} + +export interface TraitExpressionInstanceFn extends Fn { + return: this["arg0"] extends TraitExpression + ? Pipe + : never +} + +export interface TraitExpressionStaticFn extends Fn { + return: this["arg0"] extends TraitExpression + ? Pipe + : never +} export type Implements> = ( @@ -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) diff --git a/src/tests.ts b/src/tests.ts index ffb6a18..710a660 100644 --- a/src/tests.ts +++ b/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 { - readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date } -} +// interface ActiveStatefulSubscriptionAbstractMembers extends TraitAbstractMembers { +// readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date } +// } -const ActiveStatefulSubscription = trait( - abstract(), - Super => class ActiveStatefulSubscription extends Super {}, -) +// const ActiveStatefulSubscription = trait( +// abstract(), +// Super => class ActiveStatefulSubscription extends Super {}, +// ) class TestSuperclass { diff --git a/src/trait.ts b/src/trait.ts index 4d5ea36..a028dc8 100644 --- a/src/trait.ts +++ b/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[], + Super extends TraitExpression, Abstract extends {}, ImplClass extends Class<{}, []>, > { @@ -54,7 +54,7 @@ export interface TraitOwnImplClassFn extends Fn { export type TraitOwnImplClass = Call export interface TraitOwnImplInstanceFn extends Fn { - return: this["arg0"] extends Trait + return: this["arg0"] extends Trait ? InstanceType : never } @@ -77,6 +77,22 @@ export interface TraitOwnInstanceFn extends Fn { export type TraitOwnInstance = Call +export interface TraitSupertraitsFn extends Fn { + return: this["arg0"] extends Trait + ? Call + : never +} + +export interface TraitAbstractFn extends Fn { + return: this["arg0"] extends Trait + ? Call, + 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, )