diff --git a/src/Trait.ts b/src/Trait.ts index 6018376..76228c6 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,5 +1,5 @@ import { Fn, Pipe, Tuples } from "hotscript" -import { AbstractClass, Class, Opaque } from "type-fest" +import { AbstractClass, Class, Opaque, UnwrapOpaque } from "type-fest" import { AbstractTag, TraitExpression, emptyTraitExpression } from "." import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" @@ -16,14 +16,14 @@ export type AddAbstractToImplClass< ) export type RemoveAbstractFromImplClass< - ImplClassWithAbstract extends Class, + ImplClassWithAbstract extends Opaque, TraitApplierSuperTag>, Abstract extends {}, > = ( Class< Omit, keyof Abstract>, ConstructorParameters > & - StaticMembers + UnwrapOpaque> ) @@ -138,12 +138,10 @@ export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper" export function trait< Abstract extends {}, - ImplClassWithAbstract extends Class, + ImplClassWithAbstract extends Opaque, TraitApplierSuperTag>, >( - abstract: Opaque, - apply: (Super: Opaque, TraitApplierSuperTag>) => ( - Opaque - ), + abstract: Opaque, + apply: (Super: Opaque, TraitApplierSuperTag>) => ImplClassWithAbstract, ) { return new Trait( emptyTraitExpression, diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 9bbdbb2..cd58e47 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -12,9 +12,9 @@ import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" export class TraitExpression< - Superclass extends AbstractClass<{}>, - OwnTraits extends Trait[], - AllTraits extends Trait[], + Superclass extends AbstractClass<{}>, + const OwnTraits extends Trait[], + const AllTraits extends Trait[], > { constructor( readonly superclass: Superclass, @@ -51,13 +51,13 @@ export class TraitExpression< } subtrait< - SubtraitAbstract extends Implements, - SubtraitImplClassWithAbstract extends Class, + This extends TraitExpression, + SubtraitAbstract extends Implements, + SubtraitImplClassWithAbstract extends Opaque, TraitApplierSuperTag>, >( - abstract: (expression: typeof this) => Opaque, - apply: (Super: Opaque, TraitApplierSuperTag>) => ( - Opaque - ), + this: This, + abstract: (expression: This) => Opaque, + apply: (Super: Opaque, TraitApplierSuperTag>) => SubtraitImplClassWithAbstract, ) { return new Trait( this, @@ -99,11 +99,7 @@ export namespace TraitExpression { } } -export const emptyTraitExpression = new TraitExpression( - TraitExpression.NullSuperclass, - [] as const, - [] as const, -) +export const emptyTraitExpression = new TraitExpression(TraitExpression.NullSuperclass, [], []) export type Implements> = ( diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index a4b5b67..fc7c04e 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -66,11 +66,11 @@ type BuildTraitExpression< class TraitExpressionBuilder< - Super extends AbstractClass<{}>, - OwnTraits extends Trait[], - AllTraits extends Trait[], + Superclass extends AbstractClass<{}>, + const OwnTraits extends Trait[], + const AllTraits extends Trait[], > { - constructor(private expression: TraitExpression) {} + constructor(private expression: TraitExpression) {} extends< Super extends AbstractClass @@ -87,25 +87,25 @@ class TraitExpressionBuilder< } expresses< - Traits extends Trait[] + const Traits extends Trait[] >( ...traits: Traits ): TraitExpressionBuilder< - Super, + Superclass, [...OwnTraits, ...Traits], [...AllTraits, ...SpreadSupertraits] > { return new TraitExpressionBuilder( new TraitExpression( this.expression.superclass, - [...this.expression.ownTraits, ...traits] as const, - [...this.expression.allTraits, ...this.spreadSupertraits(traits)] as const, + [...this.expression.ownTraits, ...traits], + [...this.expression.allTraits, ...this.spreadSupertraits(traits)], ) - ) as any + ) } private spreadSupertraits< - Traits extends Trait< + const Traits extends Trait< TraitExpression[]>, any, any @@ -120,7 +120,7 @@ class TraitExpressionBuilder< } build() { - return this.expression as BuildTraitExpression + return this.expression as BuildTraitExpression } then(fn: (expression: ReturnType) => V): V { diff --git a/src/lib.ts b/src/lib.ts index 9c96c68..9fc1b8f 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -1,3 +1,8 @@ export { - AbstractTag, Implements, TraitApplierSuperTag, abstract, expression, trait, type Trait, type TraitExpression + Implements, + abstract, + expression, + trait, + type Trait, + type TraitExpression, } from "." diff --git a/src/tests.ts b/src/tests.ts index f8bede5..dd89c0e 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,17 +1,18 @@ -import { Simplify } from "type-fest" import { Implements, Trait, abstract, expression, trait } from "." -import { Pipe } from "hotscript" const PrintsHelloOnNew = trait( abstract(), Super => class PrintsHelloOnNew extends Super { + static readonly isPrintsHelloOnNew = true + constructor(...args: any[]) { super(...args) console.log("Hello!") } }, ) +type PrintsHelloOnNewClass = Trait.Class const Identifiable = () => trait( abstract<{ readonly id: ID }>(), @@ -34,6 +35,7 @@ const StatefulSubscription = trait( Super => class StatefulSubscription extends Super {}, ) +type StatefulSubscriptionClass = Trait.Class const ActiveStatefulSubscription = expression .expresses(StatefulSubscription) @@ -51,7 +53,7 @@ const ActiveStatefulSubscription = expression Super => class ActiveStatefulSubscription extends Super {}, ) -type T = Trait.Instance +// type T = Trait.Instance class TestSuperclass {