From 1a88ceb296479c80d3c40a5e0de0c60a3a67fe39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 02:27:50 +0100 Subject: [PATCH 01/68] Static implements tests --- src/tests.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tests.ts b/src/tests.ts index 7773ed8..5a3e955 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -84,3 +84,9 @@ class User extends exp.extends implements Implements { } console.log(new User()) + + +declare function StaticImplements(target: { issou: string }, context: any): typeof target + +@StaticImplements +class Gneugneu {} -- 2.49.1 From e31ddeaa6e7237242ced0109063f102414ede65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 14:30:10 +0100 Subject: [PATCH 02/68] Static abstract --- src/Trait.ts | 71 ++++++++++++++++++++--------------- src/TraitExpression.ts | 26 +++++++++---- src/TraitExpressionBuilder.ts | 21 ++++++----- src/tests.ts | 13 +++++-- 4 files changed, 81 insertions(+), 50 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 84516b2..8c0c210 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -9,43 +9,52 @@ export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper" export type AddAbstractToImplClass< - ImplClass extends Class<{}, []>, - Abstract extends {}, + ImplClass extends Class<{}, []>, + Abstract extends {}, + StaticAbstract extends {}, > = ( Class< Abstract & InstanceType, ConstructorParameters > & + StaticAbstract & StaticMembers ) export type RemoveAbstractFromImplClass< ImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, Abstract extends {}, + StaticAbstract extends {}, > = ( Class< Omit, keyof Abstract>, ConstructorParameters > & - Omit, "_tag"> + Omit, keyof StaticAbstract | "_tag"> ) export class Trait< - Supertraits extends TraitExpression[], Trait[]>, - Abstract extends {}, - ImplClass extends Class<{}, []>, + Supertraits extends TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[], + Trait[] + >, + Abstract extends {}, + StaticAbstract extends {}, + ImplClass extends Class<{}, []>, > { constructor( - readonly supertraits: Supertraits, - readonly abstract: Abstract, - readonly apply: (Super: AbstractClass<{}>) => ImplClass, + readonly supertraits: Supertraits, + readonly abstract: Abstract, + readonly staticAbstract: StaticAbstract, + readonly apply: (Super: AbstractClass<{}>) => ImplClass, ) {} } export namespace Trait { export type OwnSupertraits = ( - T extends Trait + T extends Trait ? Supertraits : never ) @@ -54,7 +63,7 @@ export namespace Trait { } export type OwnAbstract = ( - T extends Trait + T extends Trait ? Abstract : never ) @@ -62,8 +71,17 @@ export namespace Trait { return: Trait.OwnAbstract } + export type OwnStaticAbstract = ( + T extends Trait + ? StaticAbstract + : never + ) + export interface OwnStaticAbstractFn extends Fn { + return: Trait.OwnAbstract + } + export type OwnImplClass = ( - T extends Trait + T extends Trait ? ImplClass : never ) @@ -72,38 +90,28 @@ export namespace Trait { } export type OwnImplInstance = ( - T extends Trait - ? InstanceType - : never + InstanceType> ) export interface OwnImplInstanceFn extends Fn { return: Trait.OwnImplInstance } export type OwnClass = ( - T extends Trait - ? AddAbstractToImplClass - : never + AddAbstractToImplClass, Trait.OwnAbstract, Trait.OwnStaticAbstract> ) export interface OwnClassFn extends Fn { return: Trait.OwnClass } export type OwnInstance = ( - T extends Trait - ? InstanceType< - AddAbstractToImplClass - > - : never + InstanceType> ) export interface OwnInstanceFn extends Fn { return: Trait.OwnInstance } export type Supertraits = ( - T extends Trait - ? TraitExpression.AllTraits - : never + TraitExpression.AllTraits> ) export interface SupertraitsFn extends Fn { return: Trait.Supertraits @@ -144,14 +152,17 @@ export namespace Trait { export function trait< Abstract extends {}, + StaticAbstract extends {}, ImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, >( - abstract: Opaque, - apply: (Super: AbstractClass & { _tag: TraitApplierSuperTag }) => ImplClassWithAbstract, + abstract: Opaque, + staticAbstract: Opaque, + apply: (Super: AbstractClass & { _tag: TraitApplierSuperTag }) => ImplClassWithAbstract, ) { return new Trait( emptyTraitExpression, - abstract as Abstract, - apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, + abstract as Abstract, + staticAbstract as StaticAbstract, + apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, ) } diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index d5bfed3..20ddbc5 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -14,8 +14,8 @@ import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" export class TraitExpression< Superclass extends AbstractClass<{}>, - const OwnTraits extends Trait[], - const AllTraits extends Trait[], + const OwnTraits extends Trait[], + const AllTraits extends Trait[], > { constructor( readonly superclass: Superclass, @@ -52,17 +52,20 @@ export class TraitExpression< subtrait< This extends TraitExpression, SubtraitAbstract extends Implements, + SubtraitStaticAbstract extends StaticImplements, SubtraitImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, >( - this: This, - abstract: (expression: This) => Opaque, - apply: (Super: AbstractClass & { _tag: TraitApplierSuperTag }) => SubtraitImplClassWithAbstract, + this: This, + abstract: (expression: This) => Opaque, + staticAbstract: (expression: This) => Opaque, + apply: (Super: AbstractClass & { _tag: TraitApplierSuperTag }) => SubtraitImplClassWithAbstract, ) { return new Trait( this, // {} as RemoveSupertraitsAbstractFromAbstract>, - {} as SubtraitAbstract, // TODO: find a way to cleanly substract Implements from this. - apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, + {} as SubtraitAbstract, // TODO: find a way to cleanly substract Implements from this. + {} as SubtraitStaticAbstract, + apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, ) } } @@ -111,3 +114,12 @@ export type Implements> = ( SimplifyFn, ]> ) + +export type StaticImplements> = ( + Pipe, + ExtendFn, + SimplifyFn, + ]> +) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index c1f5064..8ab8d30 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -5,7 +5,7 @@ import { TraitExpression, emptyTraitExpression } from "./TraitExpression" import { ExtendableFn, StaticMembersFn } from "./util" -type SpreadSupertraits[]> = ( +type SpreadSupertraits[]> = ( Call< Tuples.FlatMap, Traits @@ -18,7 +18,7 @@ interface PrependTraitSupertraitsFn extends Fn { type AbstractMembersExtendable< Superclass extends AbstractClass<{}>, - Traits extends Trait[], + Traits extends Trait[], > = ( Pipe, @@ -28,7 +28,7 @@ type AbstractMembersExtendable< type ImplInstanceExtendable< Superclass extends AbstractClass<{}>, - Traits extends Trait[], + Traits extends Trait[], > = ( Pipe, @@ -38,7 +38,7 @@ type ImplInstanceExtendable< type ImplStaticMembersExtendable< Superclass extends AbstractClass<{}>, - Traits extends Trait[], + Traits extends Trait[], > = ( Pipe, @@ -50,8 +50,8 @@ type ImplStaticMembersExtendable< type BuildTraitExpression< Superclass extends AbstractClass<{}>, - OwnTraits extends Trait[], - AllTraits extends Trait[], + OwnTraits extends Trait[], + AllTraits extends Trait[], > = ( AbstractMembersExtendable extends false ? "Type conflict between the traits abstract members and/or the superclass instance." @@ -65,8 +65,8 @@ type BuildTraitExpression< class TraitExpressionBuilder< Superclass extends AbstractClass<{}>, - const OwnTraits extends Trait[], - const AllTraits extends Trait[], + const OwnTraits extends Trait[], + const AllTraits extends Trait[], > { constructor(private expression: TraitExpression) {} @@ -85,7 +85,7 @@ class TraitExpressionBuilder< } expresses< - const Traits extends Trait[] + const Traits extends Trait[] >( ...traits: Traits ): TraitExpressionBuilder< @@ -104,7 +104,8 @@ class TraitExpressionBuilder< private spreadSupertraits< const Traits extends Trait< - TraitExpression[]>, + TraitExpression[]>, + any, any, any >[] diff --git a/src/tests.ts b/src/tests.ts index 5a3e955..c3194b2 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,10 +1,11 @@ import { Trait, trait } from "./Trait" -import { Implements } from "./TraitExpression" +import { Implements, StaticImplements } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" import { abstract } from "./abstract" const PrintsHelloOnNew = trait( + abstract(), abstract(), Super => class PrintsHelloOnNew extends Super { static readonly isPrintsHelloOnNew = true @@ -19,6 +20,7 @@ type PrintsHelloOnNewClass = Trait.Class const Identifiable = () => trait( abstract<{ readonly id: ID }>(), + abstract(), Super => class Identifiable extends Super { equals(el: Identifiable) { return this.id === el.id @@ -35,6 +37,7 @@ const StatefulSubscription = trait( { _tag: "expired", expiredSince: Date } ) }>(), + abstract(), Super => class StatefulSubscription extends Super {}, ) @@ -53,6 +56,8 @@ const ActiveStatefulSubscription = expression return abstract() }, + exp => abstract>(), + Super => class ActiveStatefulSubscription extends Super {}, ) @@ -86,7 +91,9 @@ class User extends exp.extends implements Implements { console.log(new User()) -declare function StaticImplements(target: { issou: string }, context: any): typeof target +declare function StaticImplements(target: { issou: string }, context: any): void @StaticImplements -class Gneugneu {} +class Gneugneu { + // static issou: string = "juif" +} -- 2.49.1 From e6d8a10f9853a4499b431a66c6c31d5926925cdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 14:38:23 +0100 Subject: [PATCH 03/68] StaticImplements -> ImplementsStatic --- src/TraitExpression.ts | 8 ++++++-- src/tests.ts | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 20ddbc5..da6244d 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -49,10 +49,14 @@ export class TraitExpression< ) as any } + implementsStatic(target: ImplementsStatic, context: any) { + return {} + } + subtrait< This extends TraitExpression, SubtraitAbstract extends Implements, - SubtraitStaticAbstract extends StaticImplements, + SubtraitStaticAbstract extends ImplementsStatic, SubtraitImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, >( this: This, @@ -115,7 +119,7 @@ export type Implements> = ( ]> ) -export type StaticImplements> = ( +export type ImplementsStatic> = ( Pipe, diff --git a/src/tests.ts b/src/tests.ts index c3194b2..3426d4d 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,5 +1,5 @@ import { Trait, trait } from "./Trait" -import { Implements, StaticImplements } from "./TraitExpression" +import { Implements, ImplementsStatic, StaticImplements } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" import { abstract } from "./abstract" @@ -80,7 +80,9 @@ const exp = expression .build() type Abs = Implements +type AbsStatic = ImplementsStatic +@exp.implementsStatic class User extends exp.extends implements Implements { readonly isStatefulSubscription: true = true readonly isActiveStatefulSubscription: true = true -- 2.49.1 From a64f9f46d71806bbad79d29dde4b8fcadaaa3cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 14:39:18 +0100 Subject: [PATCH 04/68] Fix --- src/Trait.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Trait.ts b/src/Trait.ts index 8c0c210..c049304 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -77,7 +77,7 @@ export namespace Trait { : never ) export interface OwnStaticAbstractFn extends Fn { - return: Trait.OwnAbstract + return: Trait.OwnStaticAbstract } export type OwnImplClass = ( -- 2.49.1 From 4e59c60cdc1cf64ddcd96e73adcf89550076718e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 14:41:38 +0100 Subject: [PATCH 05/68] implementsStatic fix --- src/TraitExpression.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index da6244d..0c0f0f0 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -49,9 +49,7 @@ export class TraitExpression< ) as any } - implementsStatic(target: ImplementsStatic, context: any) { - return {} - } + implementsStatic(target: ImplementsStatic, context: any) {} subtrait< This extends TraitExpression, -- 2.49.1 From 7191b35c7a23b8e27d0e27d961392f061322a35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 14:46:24 +0100 Subject: [PATCH 06/68] Working implementsStatic --- src/tests.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/tests.ts b/src/tests.ts index 3426d4d..8f35136 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,5 +1,5 @@ import { Trait, trait } from "./Trait" -import { Implements, ImplementsStatic, StaticImplements } from "./TraitExpression" +import { Implements, ImplementsStatic } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" import { abstract } from "./abstract" @@ -56,7 +56,7 @@ const ActiveStatefulSubscription = expression return abstract() }, - exp => abstract>(), + exp => abstract>(), Super => class ActiveStatefulSubscription extends Super {}, ) @@ -91,11 +91,3 @@ class User extends exp.extends implements Implements { } console.log(new User()) - - -declare function StaticImplements(target: { issou: string }, context: any): void - -@StaticImplements -class Gneugneu { - // static issou: string = "juif" -} -- 2.49.1 From 3cf573386960a7360d450413f719acfc2c6b1756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 18:28:50 +0100 Subject: [PATCH 07/68] Fixed static abstract apply --- src/Trait.ts | 10 ++++++---- src/TraitExpression.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index c049304..1612d03 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -14,7 +14,9 @@ export type AddAbstractToImplClass< StaticAbstract extends {}, > = ( Class< - Abstract & InstanceType, + Abstract & + InstanceType, + ConstructorParameters > & StaticAbstract & @@ -22,7 +24,7 @@ export type AddAbstractToImplClass< ) export type RemoveAbstractFromImplClass< - ImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, + ImplClassWithAbstract extends Class & StaticAbstract & { _tag: TraitApplierSuperTag }, Abstract extends {}, StaticAbstract extends {}, > = ( @@ -153,11 +155,11 @@ export namespace Trait { export function trait< Abstract extends {}, StaticAbstract extends {}, - ImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, + ImplClassWithAbstract extends Class & StaticAbstract & { _tag: TraitApplierSuperTag }, >( abstract: Opaque, staticAbstract: Opaque, - apply: (Super: AbstractClass & { _tag: TraitApplierSuperTag }) => ImplClassWithAbstract, + apply: (Super: AbstractClass & StaticAbstract & { _tag: TraitApplierSuperTag }) => ImplClassWithAbstract, ) { return new Trait( emptyTraitExpression, diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 0c0f0f0..d3ea079 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -55,7 +55,7 @@ export class TraitExpression< This extends TraitExpression, SubtraitAbstract extends Implements, SubtraitStaticAbstract extends ImplementsStatic, - SubtraitImplClassWithAbstract extends Class & { _tag: TraitApplierSuperTag }, + SubtraitImplClassWithAbstract extends Class & SubtraitStaticAbstract & { _tag: TraitApplierSuperTag }, >( this: This, abstract: (expression: This) => Opaque, -- 2.49.1 From 688e01c96ceb008060e2f86ee105059827de4131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 18:29:18 +0100 Subject: [PATCH 08/68] Added export --- src/lib.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.ts b/src/lib.ts index e7f6bb7..f94e03a 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -1,4 +1,4 @@ export { trait, type Trait } from "./Trait" -export { Implements, type TraitExpression } from "./TraitExpression" +export { Implements, ImplementsStatic, type TraitExpression } from "./TraitExpression" export { expression } from "./TraitExpressionBuilder" export { abstract } from "./abstract" -- 2.49.1 From 48c64178f5f938b19f0b9cd85d648b4863a89949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 18:35:15 +0100 Subject: [PATCH 09/68] Fixed static abstract --- src/TraitExpression.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index d3ea079..d107da7 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -60,7 +60,7 @@ export class TraitExpression< this: This, abstract: (expression: This) => Opaque, staticAbstract: (expression: This) => Opaque, - apply: (Super: AbstractClass & { _tag: TraitApplierSuperTag }) => SubtraitImplClassWithAbstract, + apply: (Super: AbstractClass & SubtraitStaticAbstract & { _tag: TraitApplierSuperTag }) => SubtraitImplClassWithAbstract, ) { return new Trait( this, -- 2.49.1 From 2ad7ca0a0d5fa165a46ab9398e293ae4a552ef87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 19:18:45 +0100 Subject: [PATCH 10/68] Cleanup --- src/TraitExpression.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index d107da7..9a005a8 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -65,8 +65,8 @@ export class TraitExpression< return new Trait( this, // {} as RemoveSupertraitsAbstractFromAbstract>, - {} as SubtraitAbstract, // TODO: find a way to cleanly substract Implements from this. - {} as SubtraitStaticAbstract, + {} as SubtraitAbstract, // TODO: find a way to cleanly substract Implements from this. + {} as SubtraitStaticAbstract, // TODO: find a way to cleanly substract StaticImplements from this. apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, ) } -- 2.49.1 From 04f15b5b450e700f876ab78e846a3cd1a6a4ae09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 20:06:53 +0100 Subject: [PATCH 11/68] Trait expression uniq --- bun.lockb | Bin 155678 -> 156769 bytes package.json | 2 ++ src/TraitExpressionBuilder.ts | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bun.lockb b/bun.lockb index 1aa0c800bb2453190ab6462bf94fee3e72b2f76d..6f6c34d711ba6ce71b1f8c99b543131f3a8044a9 100755 GIT binary patch delta 28707 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 BGU@;T delta 28062 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], ) ) } -- 2.49.1 From 30ad086b9028bf3ac7b8809ae7da6d3a5774a4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 9 Feb 2024 22:49:58 +0100 Subject: [PATCH 12/68] TraitBuilder --- src/TraitBuilder.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/TraitBuilder.ts diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts new file mode 100644 index 0000000..ba22613 --- /dev/null +++ b/src/TraitBuilder.ts @@ -0,0 +1,17 @@ +import { Class } from "type-fest" +import { Trait } from "./Trait" +import { TraitExpression } from "./TraitExpression" + + +class TraitBuilder< + Supertraits extends TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[], + Trait[] + >, + Abstract extends {}, + StaticAbstract extends {}, + ImplClass extends Class<{}, []>, +> { + +} -- 2.49.1 From cb0dd26ccb597b2ab74af4eed99bb57b5dd6021d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 10 Feb 2024 00:26:19 +0100 Subject: [PATCH 13/68] Ideas --- src/TraitBuilder.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index ba22613..47579c2 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -3,6 +3,10 @@ import { Trait } from "./Trait" import { TraitExpression } from "./TraitExpression" +/* + Ideas: + - Make .abstract() and .staticAbstract() merge the declaration with the current Abstract or StaticAbstract +*/ class TraitBuilder< Supertraits extends TraitExpression< typeof TraitExpression.NullSuperclass, -- 2.49.1 From a9181567a2cd57ac5e65d33eaa9eb1b5b2b60100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 01:37:05 +0100 Subject: [PATCH 14/68] TraitBuilder --- src/Trait.ts | 2 +- src/TraitBuilder.ts | 99 +++++++++++++++++++++++++++++++---- src/TraitExpressionBuilder.ts | 2 +- 3 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 1612d03..350c818 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -5,7 +5,7 @@ import { AbstractTag } from "./abstract" import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" -export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper" +export type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" export type AddAbstractToImplClass< diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 47579c2..e782495 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,21 +1,100 @@ -import { Class } from "type-fest" +import { AbstractClass, Class } from "type-fest" import { Trait } from "./Trait" import { TraitExpression } from "./TraitExpression" +import { StaticMembers } from "./util" -/* - Ideas: - - Make .abstract() and .staticAbstract() merge the declaration with the current Abstract or StaticAbstract -*/ -class TraitBuilder< - Supertraits extends TraitExpression< +export type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" + +export type RemoveAbstractFromImplClass< + ImplClassWithAbstract extends ( + Class & + StaticAbstract & + { _tag: TraitApplierSuperTag } + ), + Abstract extends object, + StaticAbstract extends object, +> = ( + Class< + Omit, keyof Abstract>, + ConstructorParameters + > & + Omit, keyof StaticAbstract | "_tag"> +) + + +export class TraitBuilder< + SuperExpression extends TraitExpression< typeof TraitExpression.NullSuperclass, Trait[], Trait[] >, - Abstract extends {}, - StaticAbstract extends {}, - ImplClass extends Class<{}, []>, + Abstract extends object, + StaticAbstract extends object, + ImplClass extends Class, > { + constructor( + private readonly traitSuperExpression: SuperExpression, + private readonly traitAbstract: Abstract, + private readonly traitStaticAbstract: StaticAbstract, + private readonly traitApply: (Super: AbstractClass) => ImplClass, + ) {} + abstract() { + return new TraitBuilder( + this.traitSuperExpression, + {} as A, + this.traitStaticAbstract, + this.traitApply, + ) + } + + staticAbstract() { + return new TraitBuilder( + this.traitSuperExpression, + this.traitAbstract, + {} as A, + this.traitApply, + ) + } + + implement< + ImplClassWithAbstract extends ( + Class & + StaticAbstract & + { _tag: TraitApplierSuperTag } + ) + >( + apply: ( + Super: ( + AbstractClass & + StaticAbstract & + { _tag: TraitApplierSuperTag } + ) + ) => ImplClassWithAbstract + ) { + return new Trait( + this.traitSuperExpression, + this.traitAbstract, + this.traitStaticAbstract, + apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass, + ) + } + + build() { + return new Trait( + this.traitSuperExpression, + this.traitAbstract, + this.traitStaticAbstract, + this.traitApply, + ) + } } + + +export const trait = new TraitBuilder( + new TraitExpression(TraitExpression.NullSuperclass, [], []), + {}, + {}, + Super => class extends Super {}, +) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 0e9ed0d..8e5c85e 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -69,7 +69,7 @@ class TraitExpressionBuilder< const OwnTraits extends Trait[], const AllTraits extends Trait[], > { - constructor(private expression: TraitExpression) {} + constructor(private readonly expression: TraitExpression) {} extends< Super extends AbstractClass -- 2.49.1 From f849715a4079836d83d9d6d2f67465f850464eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 02:04:12 +0100 Subject: [PATCH 15/68] TraitBuilder use in tests --- src/TraitBuilder.ts | 2 +- src/tests.ts | 35 ++++++++++++++++------------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index e782495..c40a5fa 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -73,7 +73,7 @@ export class TraitBuilder< ) ) => ImplClassWithAbstract ) { - return new Trait( + return new TraitBuilder( this.traitSuperExpression, this.traitAbstract, this.traitStaticAbstract, diff --git a/src/tests.ts b/src/tests.ts index 8f35136..914ef53 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,46 +1,43 @@ -import { Trait, trait } from "./Trait" +import { Trait } from "./Trait" +import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" import { abstract } from "./abstract" -const PrintsHelloOnNew = trait( - abstract(), - abstract(), - Super => class PrintsHelloOnNew extends Super { +const PrintsHelloOnNew = trait + .implement(Super => class PrintsHelloOnNew extends Super { static readonly isPrintsHelloOnNew = true constructor(...args: any[]) { super(...args) console.log("Hello!") } - }, -) + }) + .build() + type PrintsHelloOnNewClass = Trait.Class -const Identifiable = () => trait( - abstract<{ readonly id: ID }>(), - abstract(), - Super => class Identifiable extends Super { +const Identifiable = () => trait + .abstract<{ readonly id: ID }>() + .implement(Super => class Identifiable extends Super { equals(el: Identifiable) { return this.id === el.id } - }, -) + }) + .build() -const StatefulSubscription = trait( - abstract<{ +const StatefulSubscription = trait + .abstract<{ readonly isStatefulSubscription: true readonly status: ( { _tag: "awaitingPayment" } | { _tag: "active", activeSince: Date, expiresAt?: Date } | { _tag: "expired", expiredSince: Date } ) - }>(), - abstract(), + }>() + .build() - Super => class StatefulSubscription extends Super {}, -) type StatefulSubscriptionClass = Trait.Class const ActiveStatefulSubscription = expression -- 2.49.1 From b5d97b5904e047da30a0f0133f2ed0f490dfea9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 02:07:12 +0100 Subject: [PATCH 16/68] Exports --- package.json | 2 +- src/lib.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index edf713a..347b249 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thilawyn/traitify-ts", - "version": "0.1.3", + "version": "0.1.4", "type": "module", "publishConfig": { "registry": "https://git.jvalver.de/api/packages/thilawyn/npm/" diff --git a/src/lib.ts b/src/lib.ts index f94e03a..b8918ac 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -1,4 +1,5 @@ -export { trait, type Trait } from "./Trait" +export { type Trait } from "./Trait" +export { trait } from "./TraitBuilder" export { Implements, ImplementsStatic, type TraitExpression } from "./TraitExpression" export { expression } from "./TraitExpressionBuilder" export { abstract } from "./abstract" -- 2.49.1 From 14ceae27ecd3c123d2124f75d5e95f6bdfd88762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 03:03:28 +0100 Subject: [PATCH 17/68] Regenerated lockfile --- bun.lockb | Bin 156769 -> 156769 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bun.lockb b/bun.lockb index 6f6c34d711ba6ce71b1f8c99b543131f3a8044a9..8f53293a5d25767695713af6946a36b736e7a416 100755 GIT binary patch delta 27 jcmaEOg7e`C&W0_F%BwgT<4p7n&Gih8w(G27G~ERNmx&3d delta 27 dcmaEOg7e`C&W0_F%Bwh;7@%Og&MHRJT>ymR2k!s? -- 2.49.1 From 5873926dc5d37a08bd062ce18d60dc6255d02c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 03:27:03 +0100 Subject: [PATCH 18/68] TraitExpression subtrait work --- src/TraitExpression.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 9a005a8..188edc0 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -52,22 +52,11 @@ export class TraitExpression< implementsStatic(target: ImplementsStatic, context: any) {} subtrait< - This extends TraitExpression, - SubtraitAbstract extends Implements, - SubtraitStaticAbstract extends ImplementsStatic, - SubtraitImplClassWithAbstract extends Class & SubtraitStaticAbstract & { _tag: TraitApplierSuperTag }, + This extends TraitExpression >( - this: This, - abstract: (expression: This) => Opaque, - staticAbstract: (expression: This) => Opaque, - apply: (Super: AbstractClass & SubtraitStaticAbstract & { _tag: TraitApplierSuperTag }) => SubtraitImplClassWithAbstract, + this: This ) { return new Trait( - this, - // {} as RemoveSupertraitsAbstractFromAbstract>, - {} as SubtraitAbstract, // TODO: find a way to cleanly substract Implements from this. - {} as SubtraitStaticAbstract, // TODO: find a way to cleanly substract StaticImplements from this. - apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, ) } } -- 2.49.1 From 175864950739a74d9ff187253d9f9bd5620cb902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 21:13:02 +0100 Subject: [PATCH 19/68] Complete refactoring --- src/Trait.ts | 73 +++++++++------------------------ src/TraitBuilder.ts | 4 +- src/TraitExpression.ts | 59 ++++++++++++--------------- src/TraitExpressionBuilder.ts | 76 +++++++++++++++-------------------- 4 files changed, 77 insertions(+), 135 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 350c818..fbc5f90 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,17 +1,13 @@ import { Fn, Pipe, Tuples } from "hotscript" -import { AbstractClass, Class, Opaque } from "type-fest" -import { TraitExpression, emptyTraitExpression } from "./TraitExpression" -import { AbstractTag } from "./abstract" +import { AbstractClass, Class } from "type-fest" +import { TraitExpression } from "./TraitExpression" import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" -export type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" - - export type AddAbstractToImplClass< - ImplClass extends Class<{}, []>, - Abstract extends {}, - StaticAbstract extends {}, + ImplClass extends Class, + Abstract extends object, + StaticAbstract extends object, > = ( Class< Abstract & @@ -23,45 +19,32 @@ export type AddAbstractToImplClass< StaticMembers ) -export type RemoveAbstractFromImplClass< - ImplClassWithAbstract extends Class & StaticAbstract & { _tag: TraitApplierSuperTag }, - Abstract extends {}, - StaticAbstract extends {}, -> = ( - Class< - Omit, keyof Abstract>, - ConstructorParameters - > & - Omit, keyof StaticAbstract | "_tag"> -) - export class Trait< - Supertraits extends TraitExpression< + SuperExpression extends TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[], Trait[] >, - Abstract extends {}, - StaticAbstract extends {}, - ImplClass extends Class<{}, []>, + Abstract extends object, + StaticAbstract extends object, + ImplClass extends Class, > { constructor( - readonly supertraits: Supertraits, - readonly abstract: Abstract, - readonly staticAbstract: StaticAbstract, - readonly apply: (Super: AbstractClass<{}>) => ImplClass, + readonly superExpression: SuperExpression, + readonly abstract: Abstract, + readonly staticAbstract: StaticAbstract, + readonly apply: (Super: AbstractClass) => ImplClass, ) {} } export namespace Trait { - export type OwnSupertraits = ( - T extends Trait - ? Supertraits + export type OwnSuperExpression = ( + T extends Trait + ? SuperExpression : never ) - export interface OwnSupertraitsFn extends Fn { - return: Trait.OwnSupertraits + export interface OwnSuperExpressionFn extends Fn { + return: Trait.OwnSuperExpression } export type OwnAbstract = ( @@ -113,7 +96,7 @@ export namespace Trait { } export type Supertraits = ( - TraitExpression.AllTraits> + TraitExpression.Traits> ) export interface SupertraitsFn extends Fn { return: Trait.Supertraits @@ -150,21 +133,3 @@ export namespace Trait { return: Trait.Instance } } - - -export function trait< - Abstract extends {}, - StaticAbstract extends {}, - ImplClassWithAbstract extends Class & StaticAbstract & { _tag: TraitApplierSuperTag }, ->( - abstract: Opaque, - staticAbstract: Opaque, - apply: (Super: AbstractClass & StaticAbstract & { _tag: TraitApplierSuperTag }) => ImplClassWithAbstract, -) { - return new Trait( - emptyTraitExpression, - abstract as Abstract, - staticAbstract as StaticAbstract, - apply as any as (Super: AbstractClass<{}>) => RemoveAbstractFromImplClass, - ) -} diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index c40a5fa..6c43e8b 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -26,7 +26,6 @@ export type RemoveAbstractFromImplClass< export class TraitBuilder< SuperExpression extends TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[], Trait[] >, Abstract extends object, @@ -91,9 +90,8 @@ export class TraitBuilder< } } - export const trait = new TraitBuilder( - new TraitExpression(TraitExpression.NullSuperclass, [], []), + new TraitExpression(TraitExpression.NullSuperclass, []), {}, {}, Super => class extends Super {}, diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 188edc0..9b65e06 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,7 +1,7 @@ import { Fn, Pipe, Tuples } from "hotscript" -import { AbstractClass, Class, Opaque } from "type-fest" -import { RemoveAbstractFromImplClass, Trait, TraitApplierSuperTag } from "./Trait" -import { AbstractTag } from "./abstract" +import { AbstractClass } from "type-fest" +import { Trait } from "./Trait" +import { TraitBuilder } from "./TraitBuilder" import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" @@ -13,19 +13,17 @@ import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" export class TraitExpression< - Superclass extends AbstractClass<{}>, - const OwnTraits extends Trait[], - const AllTraits extends Trait[], + Superclass extends AbstractClass, + const Traits extends Trait[], > { constructor( readonly superclass: Superclass, - readonly ownTraits: OwnTraits, - readonly allTraits: AllTraits, + readonly traits: Traits, ) {} get extends(): ( AbstractClass< - Pipe, // Map all the traits to the instance of their implementation class Tuples.Prepend>, // Add the instance of the superclass at the top of the list ExtendFn, // Reduce to a single instance that extends all the instances in the list @@ -35,7 +33,7 @@ export class TraitExpression< ConstructorParameters > & - Pipe, // Map all the traits to their implementation class Tuples.Prepend, // Add the superclass at the top of the list Tuples.Map, // Map all the classes to an object containing their static members @@ -43,7 +41,7 @@ export class TraitExpression< SimplifyFn, // Make readable for IDEs ]> ) { - return this.allTraits.reduce( + return this.traits.reduce( (previous, trait) => trait.apply(previous), this.superclass, ) as any @@ -52,11 +50,15 @@ export class TraitExpression< implementsStatic(target: ImplementsStatic, context: any) {} subtrait< - This extends TraitExpression + This extends TraitExpression >( this: This ) { - return new Trait( + return new TraitBuilder( + this, + {}, + {}, + Super => class extends Super {}, ) } } @@ -67,7 +69,7 @@ export namespace TraitExpression { } export type Superclass = ( - T extends TraitExpression + T extends TraitExpression ? Superclass : never ) @@ -75,40 +77,29 @@ export namespace TraitExpression { return: TraitExpression.Superclass } - export type OwnTraits = ( - T extends TraitExpression - ? OwnTraits + export type Traits = ( + T extends TraitExpression + ? Traits : never ) - export interface OwnTraitsFn extends Fn { - return: TraitExpression.OwnTraits - } - - export type AllTraits = ( - T extends TraitExpression - ? AllTraits - : never - ) - export interface AllTraitsFn extends Fn { - return: TraitExpression.AllTraits + export interface TraitsFn extends Fn { + return: TraitExpression.Traits } } -export const emptyTraitExpression = new TraitExpression(TraitExpression.NullSuperclass, [], []) - -export type Implements> = ( +export type Implements> = ( Pipe, ExtendFn, SimplifyFn, ]> ) -export type ImplementsStatic> = ( +export type ImplementsStatic> = ( Pipe, ExtendFn, SimplifyFn, diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 8e5c85e..23c76de 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -2,7 +2,7 @@ import { Call, Fn, Pipe, Tuples } from "hotscript" import { uniq } from "lodash-es" import { AbstractClass } from "type-fest" import { Trait } from "./Trait" -import { TraitExpression, emptyTraitExpression } from "./TraitExpression" +import { TraitExpression } from "./TraitExpression" import { ExtendableFn, StaticMembersFn } from "./util" @@ -51,76 +51,64 @@ type ImplStaticMembersExtendable< type BuildTraitExpression< Superclass extends AbstractClass<{}>, - OwnTraits extends Trait[], - AllTraits extends Trait[], + Traits extends Trait[], > = ( - AbstractMembersExtendable extends false + AbstractMembersExtendable extends false ? "Type conflict between the traits abstract members and/or the superclass instance." - : ImplInstanceExtendable extends false + : ImplInstanceExtendable extends false ? "Type conflict between the traits implementation instances and/or the superclass instance." - : ImplStaticMembersExtendable extends false + : ImplStaticMembersExtendable extends false ? "Type conflict between the traits implementation static members and/or the superclass static members." - : TraitExpression + : TraitExpression ) class TraitExpressionBuilder< - Superclass extends AbstractClass<{}>, - const OwnTraits extends Trait[], - const AllTraits extends Trait[], + Superclass extends AbstractClass, + const Traits extends Trait[], > { - constructor(private readonly expression: TraitExpression) {} + constructor( + private readonly expressionSuperclass: Superclass, + private readonly expressionTraits: Traits, + ) {} extends< - Super extends AbstractClass + Super extends AbstractClass >( superclass: Super ) { return new TraitExpressionBuilder( - new TraitExpression( - superclass, - this.expression.ownTraits, - this.expression.allTraits, - ) + superclass, + this.expressionTraits, ) } expresses< - const Traits extends Trait[] + const T extends Trait[] >( - ...traits: Traits + ...traits: T ): TraitExpressionBuilder< Superclass, - [...OwnTraits, ...Traits], - [...AllTraits, ...SpreadSupertraits] + [...Traits, ...SpreadSupertraits] > { return new TraitExpressionBuilder( - new TraitExpression( - this.expression.superclass, - uniq([...this.expression.ownTraits, ...traits]) as [...OwnTraits, ...Traits], - uniq([...this.expression.allTraits, ...this.spreadSupertraits(traits)]) as [...AllTraits, ...SpreadSupertraits], - ) + this.expressionSuperclass, + + uniq([ + ...this.expressionTraits, + ...traits.flatMap(trait => [ + ...trait.superExpression.allTraits, + trait, + ]), + ]) as [...Traits, ...SpreadSupertraits], ) } - private spreadSupertraits< - const Traits extends Trait< - TraitExpression[]>, - any, - any, - any - >[] - >( - traits: Traits - ) { - return traits.flatMap(trait => [ - ...trait.supertraits.allTraits, - trait, - ]) as SpreadSupertraits - } - build() { - return this.expression as BuildTraitExpression + return new TraitExpression( + this.expressionSuperclass, + this.expressionTraits, + ) as BuildTraitExpression } then(fn: (expression: ReturnType) => V): V { @@ -128,4 +116,4 @@ class TraitExpressionBuilder< } } -export const expression = new TraitExpressionBuilder(emptyTraitExpression) +export const expression = new TraitExpressionBuilder(TraitExpression.NullSuperclass, []) -- 2.49.1 From a065daec1e88b3ff48f3008ceaef9e55f223ff43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 21:57:48 +0100 Subject: [PATCH 20/68] extendAbstract --- src/TraitBuilder.ts | 13 +++++++++++++ src/tests.ts | 16 ++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 6c43e8b..24d62ea 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -57,6 +57,19 @@ export class TraitBuilder< ) } + extendAbstract< + A extends Abstract + >( + abstract: (Super: AbstractClass) => AbstractClass + ) { + return new TraitBuilder( + this.traitSuperExpression, + {} as A, + this.traitStaticAbstract, + this.traitApply, + ) + } + implement< ImplClassWithAbstract extends ( Class & diff --git a/src/tests.ts b/src/tests.ts index 914ef53..688a352 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -28,14 +28,22 @@ const Identifiable = () => trait .build() const StatefulSubscription = trait - .abstract<{ - readonly isStatefulSubscription: true - readonly status: ( + // .abstract<{ + // readonly isStatefulSubscription: true + // readonly status: ( + // { _tag: "awaitingPayment" } | + // { _tag: "active", activeSince: Date, expiresAt?: Date } | + // { _tag: "expired", expiredSince: Date } + // ) + // }>() + .extendAbstract(Super => class extends Super { + readonly isStatefulSubscription!: true + readonly status!: ( { _tag: "awaitingPayment" } | { _tag: "active", activeSince: Date, expiresAt?: Date } | { _tag: "expired", expiredSince: Date } ) - }>() + }) .build() type StatefulSubscriptionClass = Trait.Class -- 2.49.1 From 0b0ca2326c454fbc49a3d38b561719f28fe6b625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 22:33:23 +0100 Subject: [PATCH 21/68] extendStaticAbstract --- src/TraitBuilder.ts | 21 +++++++++++++++------ src/tests.ts | 20 ++++++-------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 24d62ea..f0719d4 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,6 +1,6 @@ import { AbstractClass, Class } from "type-fest" import { Trait } from "./Trait" -import { TraitExpression } from "./TraitExpression" +import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" import { StaticMembers } from "./util" @@ -48,6 +48,17 @@ export class TraitBuilder< ) } + extendAbstract( + _: (Super: AbstractClass & Abstract>) => AbstractClass + ) { + return new TraitBuilder( + this.traitSuperExpression, + {} as A, + this.traitStaticAbstract, + this.traitApply, + ) + } + staticAbstract() { return new TraitBuilder( this.traitSuperExpression, @@ -57,15 +68,13 @@ export class TraitBuilder< ) } - extendAbstract< - A extends Abstract - >( - abstract: (Super: AbstractClass) => AbstractClass + extendStaticAbstract( + _: (Super: AbstractClass & StaticAbstract>) => AbstractClass ) { return new TraitBuilder( this.traitSuperExpression, + this.traitAbstract, {} as A, - this.traitStaticAbstract, this.traitApply, ) } diff --git a/src/tests.ts b/src/tests.ts index 688a352..8067fbf 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -51,20 +51,12 @@ type StatefulSubscriptionClass = Trait.Class const ActiveStatefulSubscription = expression .expresses(StatefulSubscription) .build() - .subtrait( - exp => { - interface IActiveStatefulSubscription extends Implements { - readonly isActiveStatefulSubscription: true - readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date } - } - - return abstract() - }, - - exp => abstract>(), - - Super => class ActiveStatefulSubscription extends Super {}, - ) + .subtrait() + .extendAbstract(Super => class extends Super { + readonly isActiveStatefulSubscription!: true + readonly status!: { _tag: "active", activeSince: Date, expiresAt?: Date } + }) + .build() type ActiveStatefulSubscriptionClass = Trait.Class -- 2.49.1 From d0b8981d45fb120bb2c4be6427c4e839597f014f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 22:59:37 +0100 Subject: [PATCH 22/68] Fix --- src/abstract.ts | 10 ---------- src/lib.ts | 1 - src/tests.ts | 1 - 3 files changed, 12 deletions(-) delete mode 100644 src/abstract.ts diff --git a/src/abstract.ts b/src/abstract.ts deleted file mode 100644 index c6502e4..0000000 --- a/src/abstract.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Opaque } from "type-fest" - - -export type AbstractTag = "@thilawyn/traitify-ts/Abstract" - -export function abstract< - Abstract extends {} = {} ->() { - return {} as Opaque -} diff --git a/src/lib.ts b/src/lib.ts index b8918ac..f268d87 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -2,4 +2,3 @@ export { type Trait } from "./Trait" export { trait } from "./TraitBuilder" export { Implements, ImplementsStatic, type TraitExpression } from "./TraitExpression" export { expression } from "./TraitExpressionBuilder" -export { abstract } from "./abstract" diff --git a/src/tests.ts b/src/tests.ts index 8067fbf..625eede 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -2,7 +2,6 @@ import { Trait } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" -import { abstract } from "./abstract" const PrintsHelloOnNew = trait -- 2.49.1 From bc4b1b6492966eeb00276a789a99d7ca9d20bbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 14 Feb 2024 23:18:17 +0100 Subject: [PATCH 23/68] Fix --- src/TraitExpressionBuilder.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 23c76de..b6b35a6 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -84,7 +84,15 @@ class TraitExpressionBuilder< } expresses< - const T extends Trait[] + const T extends Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + any, + any, + any + >[] >( ...traits: T ): TraitExpressionBuilder< @@ -97,7 +105,7 @@ class TraitExpressionBuilder< uniq([ ...this.expressionTraits, ...traits.flatMap(trait => [ - ...trait.superExpression.allTraits, + ...trait.superExpression.traits, trait, ]), ]) as [...Traits, ...SpreadSupertraits], -- 2.49.1 From ceba99326d1d98fe66585be642c19e70a0019f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 15 Feb 2024 18:11:40 +0100 Subject: [PATCH 24/68] Fix --- src/TraitBuilder.ts | 27 +++++++++++++++++++++++---- src/TraitExpression.ts | 7 ------- src/tests.ts | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index f0719d4..94f7a53 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,7 +1,8 @@ +import { Pipe, Tuples } from "hotscript" import { AbstractClass, Class } from "type-fest" import { Trait } from "./Trait" -import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" -import { StaticMembers } from "./util" +import { TraitExpression } from "./TraitExpression" +import { ExtendFn, SimplifyFn, StaticMembers } from "./util" export type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" @@ -49,7 +50,17 @@ export class TraitBuilder< } extendAbstract( - _: (Super: AbstractClass & Abstract>) => AbstractClass + _: ( + Super: AbstractClass< + Pipe, + Tuples.Append, + ExtendFn, + SimplifyFn, + ]> + > + ) => AbstractClass ) { return new TraitBuilder( this.traitSuperExpression, @@ -69,7 +80,15 @@ export class TraitBuilder< } extendStaticAbstract( - _: (Super: AbstractClass & StaticAbstract>) => AbstractClass + _: (Super: AbstractClass< + Pipe, + Tuples.Append, + ExtendFn, + SimplifyFn, + ]> + >) => AbstractClass ) { return new TraitBuilder( this.traitSuperExpression, diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 9b65e06..96efaab 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -5,13 +5,6 @@ import { TraitBuilder } from "./TraitBuilder" import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" -// type RemoveSupertraitsAbstractFromAbstract = { -// [Key in Extract]: Left[Key] -// } & { -// [Key in Exclude]: Left[Key] -// } - - export class TraitExpression< Superclass extends AbstractClass, const Traits extends Trait[], diff --git a/src/tests.ts b/src/tests.ts index 625eede..1863fce 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -62,7 +62,7 @@ type ActiveStatefulSubscriptionClass = Trait.Class Date: Thu, 15 Feb 2024 19:49:11 +0100 Subject: [PATCH 25/68] TraitBuilder work --- src/Trait.ts | 2 +- src/TraitBuilder.ts | 51 ++++++++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index fbc5f90..91df43a 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -4,7 +4,7 @@ import { TraitExpression } from "./TraitExpression" import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" -export type AddAbstractToImplClass< +type AddAbstractToImplClass< ImplClass extends Class, Abstract extends object, StaticAbstract extends object, diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 94f7a53..a825162 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -5,9 +5,30 @@ import { TraitExpression } from "./TraitExpression" import { ExtendFn, SimplifyFn, StaticMembers } from "./util" -export type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" +type SuperAbstract = ( + Pipe, + Tuples.Append, + ExtendFn, + SimplifyFn, + ]> +) -export type RemoveAbstractFromImplClass< +type SuperStaticAbstract = ( + Pipe, + Tuples.Append, + ExtendFn, + SimplifyFn, + ]> +) + + +type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" + +type RemoveAbstractFromImplClass< ImplClassWithAbstract extends ( Class & StaticAbstract & @@ -40,7 +61,7 @@ export class TraitBuilder< private readonly traitApply: (Super: AbstractClass) => ImplClass, ) {} - abstract() { + abstract>() { return new TraitBuilder( this.traitSuperExpression, {} as A, @@ -49,16 +70,10 @@ export class TraitBuilder< ) } - extendAbstract( + extendAbstract>( _: ( Super: AbstractClass< - Pipe, - Tuples.Append, - ExtendFn, - SimplifyFn, - ]> + SuperAbstract > ) => AbstractClass ) { @@ -70,7 +85,7 @@ export class TraitBuilder< ) } - staticAbstract() { + staticAbstract>() { return new TraitBuilder( this.traitSuperExpression, this.traitAbstract, @@ -79,15 +94,9 @@ export class TraitBuilder< ) } - extendStaticAbstract( + extendStaticAbstract>( _: (Super: AbstractClass< - Pipe, - Tuples.Append, - ExtendFn, - SimplifyFn, - ]> + SuperStaticAbstract >) => AbstractClass ) { return new TraitBuilder( @@ -101,7 +110,7 @@ export class TraitBuilder< implement< ImplClassWithAbstract extends ( Class & - StaticAbstract & + SuperStaticAbstract & { _tag: TraitApplierSuperTag } ) >( -- 2.49.1 From fe667e87fe55ef3aaf9d664d130e55a506c8c061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 15 Feb 2024 21:00:12 +0100 Subject: [PATCH 26/68] TraitExpression work --- src/TraitBuilder.ts | 16 ++++++++-------- src/TraitExpression.ts | 8 ++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index a825162..b19aa8b 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -5,7 +5,7 @@ import { TraitExpression } from "./TraitExpression" import { ExtendFn, SimplifyFn, StaticMembers } from "./util" -type SuperAbstract = ( +type ExtendAbstractSuper = ( Pipe, @@ -15,7 +15,7 @@ type SuperAbstract = ( ]> ) -type SuperStaticAbstract = ( +type ExtendStaticAbstractSuper = ( Pipe, @@ -61,7 +61,7 @@ export class TraitBuilder< private readonly traitApply: (Super: AbstractClass) => ImplClass, ) {} - abstract>() { + abstract>() { return new TraitBuilder( this.traitSuperExpression, {} as A, @@ -70,10 +70,10 @@ export class TraitBuilder< ) } - extendAbstract>( + extendAbstract>( _: ( Super: AbstractClass< - SuperAbstract + ExtendAbstractSuper > ) => AbstractClass ) { @@ -85,7 +85,7 @@ export class TraitBuilder< ) } - staticAbstract>() { + staticAbstract>() { return new TraitBuilder( this.traitSuperExpression, this.traitAbstract, @@ -94,9 +94,9 @@ export class TraitBuilder< ) } - extendStaticAbstract>( + extendStaticAbstract>( _: (Super: AbstractClass< - SuperStaticAbstract + ExtendStaticAbstractSuper >) => AbstractClass ) { return new TraitBuilder( diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 96efaab..0d0147e 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -98,3 +98,11 @@ export type ImplementsStatic> = ( SimplifyFn, ]> ) + +export type TraitExpressionClass> = ( + +) + +export type TraitExpressionInstance> = ( + +) -- 2.49.1 From af8884cdee826965a9b1cad81f435caf88f2e187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 15 Feb 2024 22:29:14 +0100 Subject: [PATCH 27/68] TraitExpression work --- src/TraitExpression.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 0d0147e..73c467b 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -99,10 +99,28 @@ export type ImplementsStatic> = ( ]> ) + export type TraitExpressionClass> = ( + AbstractClass< + > & + + +) + +export type TraitExpressionConcreteClass> = ( ) export type TraitExpressionInstance> = ( ) + +export type TraitExpressionStaticMembers> = ( + Pipe, // Map all the traits to their implementation class + Tuples.Prepend, // Add the superclass at the top of the list + Tuples.Map, // Map all the classes to an object containing their static members + ExtendFn, // Reduce to a single object that extends all the objects in the list + SimplifyFn, // Make readable for IDEs + ]> +) -- 2.49.1 From 9f2c42db1432631527f68e3b0336dbf5f0d011ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 16 Feb 2024 01:14:36 +0100 Subject: [PATCH 28/68] Refactoring --- src/Trait.ts | 89 ++++++++++++++++++------------------------ src/TraitExpression.ts | 35 +++++++++++------ 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 91df43a..3f2e39f 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,23 +1,7 @@ import { Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" - - -type AddAbstractToImplClass< - ImplClass extends Class, - Abstract extends object, - StaticAbstract extends object, -> = ( - Class< - Abstract & - InstanceType, - - ConstructorParameters - > & - StaticAbstract & - StaticMembers -) +import { Extend, ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" export class Trait< @@ -82,14 +66,18 @@ export namespace Trait { } export type OwnClass = ( - AddAbstractToImplClass, Trait.OwnAbstract, Trait.OwnStaticAbstract> + AbstractClass, any[]> & + Extend<[ + Trait.OwnStaticAbstract, + StaticMembers>, + ]> ) export interface OwnClassFn extends Fn { return: Trait.OwnClass } export type OwnInstance = ( - InstanceType> + Extend<[Trait.OwnAbstract, Trait.OwnImplInstance]> ) export interface OwnInstanceFn extends Fn { return: Trait.OwnInstance @@ -101,35 +89,36 @@ export namespace Trait { export interface SupertraitsFn extends Fn { return: Trait.Supertraits } - - export type Class = ( - AbstractClass< - Trait.Instance, - any[] - > & - Pipe, - Tuples.Map, - Tuples.Map, - ExtendFn, - SimplifyFn, - ]> - ) - export interface ClassFn extends Fn { - return: Trait.Class - } - - export type Instance = ( - Pipe, - Tuples.Map, - ExtendFn, - SimplifyFn, - ]> - ) - export interface InstanceFn extends Fn { - return: Trait.Instance - } } + + +export type TraitClass> = ( + AbstractClass, any[]> & + TraitStaticMembers +) + +export type TraitConcreteClass> = ( + Class, any[]> & + TraitStaticMembers +) + +export type TraitInstance> = ( + Pipe, + Tuples.Map, + ExtendFn, + SimplifyFn, + ]> +) + +export type TraitStaticMembers> = ( + Pipe, + Tuples.Map, + Tuples.Map, + ExtendFn, + SimplifyFn, + ]> +) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 73c467b..b631dbc 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,5 +1,5 @@ import { Fn, Pipe, Tuples } from "hotscript" -import { AbstractClass } from "type-fest" +import { AbstractClass, Class } from "type-fest" import { Trait } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" @@ -59,6 +59,7 @@ export class TraitExpression< export namespace TraitExpression { export class NullSuperclass { static readonly _tag = "@thilawyn/traitify-ts/TraitExpression.NullSuperclass" + constructor(...args: any[]) {} } export type Superclass = ( @@ -102,25 +103,37 @@ export type ImplementsStatic> = ( export type TraitExpressionClass> = ( AbstractClass< + TraitExpressionInstance, + ConstructorParameters> > & - - + TraitExpressionStaticMembers ) export type TraitExpressionConcreteClass> = ( - + Class< + TraitExpressionInstance, + ConstructorParameters> + > & + TraitExpressionStaticMembers ) export type TraitExpressionInstance> = ( - + Pipe, [ + Tuples.Map, // Map all the traits to their instance representation + Tuples.Prepend< // Add the instance of the superclass at the top of the list + InstanceType> + >, + ExtendFn, // Reduce to a single object that extends all the objects in the list + SimplifyFn, // Make readable for IDEs + ]> ) export type TraitExpressionStaticMembers> = ( - Pipe, // Map all the traits to their implementation class - Tuples.Prepend, // Add the superclass at the top of the list - Tuples.Map, // Map all the classes to an object containing their static members - ExtendFn, // Reduce to a single object that extends all the objects in the list - SimplifyFn, // Make readable for IDEs + Pipe, [ + Tuples.Map, // Map all the traits to their class representation + Tuples.Prepend>, // Add the superclass at the top of the list + Tuples.Map, // Map all the classes to an object containing their static members + ExtendFn, // Reduce to a single object that extends all the objects in the list + SimplifyFn, // Make readable for IDEs ]> ) -- 2.49.1 From f37f15e466a36817c21e8c710093f25fd594e1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 16 Feb 2024 01:30:04 +0100 Subject: [PATCH 29/68] TraitBuilder work --- src/TraitBuilder.ts | 12 +++++++----- src/tests.ts | 8 ++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index b19aa8b..55d3663 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,6 +1,6 @@ import { Pipe, Tuples } from "hotscript" import { AbstractClass, Class } from "type-fest" -import { Trait } from "./Trait" +import { Trait, TraitClass, TraitConcreteClass, TraitInstance } from "./Trait" import { TraitExpression } from "./TraitExpression" import { ExtendFn, SimplifyFn, StaticMembers } from "./util" @@ -109,15 +109,17 @@ export class TraitBuilder< implement< ImplClassWithAbstract extends ( - Class & - SuperStaticAbstract & + TraitConcreteClass< + Trait + > & { _tag: TraitApplierSuperTag } ) >( apply: ( Super: ( - AbstractClass & - StaticAbstract & + TraitClass< + Trait + > & { _tag: TraitApplierSuperTag } ) ) => ImplClassWithAbstract diff --git a/src/tests.ts b/src/tests.ts index 1863fce..eb3f498 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,4 +1,4 @@ -import { Trait } from "./Trait" +import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" @@ -15,7 +15,7 @@ const PrintsHelloOnNew = trait }) .build() -type PrintsHelloOnNewClass = Trait.Class +type PrintsHelloOnNewClass = TraitClass const Identifiable = () => trait .abstract<{ readonly id: ID }>() @@ -45,7 +45,7 @@ const StatefulSubscription = trait }) .build() -type StatefulSubscriptionClass = Trait.Class +type StatefulSubscriptionClass = TraitClass const ActiveStatefulSubscription = expression .expresses(StatefulSubscription) @@ -57,7 +57,7 @@ const ActiveStatefulSubscription = expression }) .build() -type ActiveStatefulSubscriptionClass = Trait.Class +type ActiveStatefulSubscriptionClass = TraitClass class TestSuperclass { -- 2.49.1 From df54a39eeb444e70919046ea11eaff412819624f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 16 Feb 2024 03:48:30 +0100 Subject: [PATCH 30/68] Cleanup --- src/TraitBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 55d3663..bc8f7af 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,6 +1,6 @@ import { Pipe, Tuples } from "hotscript" import { AbstractClass, Class } from "type-fest" -import { Trait, TraitClass, TraitConcreteClass, TraitInstance } from "./Trait" +import { Trait, TraitClass, TraitConcreteClass } from "./Trait" import { TraitExpression } from "./TraitExpression" import { ExtendFn, SimplifyFn, StaticMembers } from "./util" -- 2.49.1 From 932d8576d9a2d9b9e8c3b2a254de9c2d1475ae3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 16 Feb 2024 19:54:48 +0100 Subject: [PATCH 31/68] Fix --- src/TraitBuilder.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index bc8f7af..acba811 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -95,9 +95,11 @@ export class TraitBuilder< } extendStaticAbstract>( - _: (Super: AbstractClass< - ExtendStaticAbstractSuper - >) => AbstractClass + _: ( + Super: AbstractClass< + ExtendStaticAbstractSuper + > + ) => AbstractClass ) { return new TraitBuilder( this.traitSuperExpression, -- 2.49.1 From 15c5548fde8054020598b7147dfcf9272aea4270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 17 Feb 2024 03:31:46 +0100 Subject: [PATCH 32/68] Fixed TraitBuilder --- src/TraitBuilder.ts | 27 +++++++++++++++++---------- src/tests.ts | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index acba811..3663194 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -29,19 +29,21 @@ type ExtendStaticAbstractSuper = ( type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" type RemoveAbstractFromImplClass< - ImplClassWithAbstract extends ( - Class & - StaticAbstract & - { _tag: TraitApplierSuperTag } - ), - Abstract extends object, - StaticAbstract extends object, + ImplClassWithAbstract extends AbstractClass, + Abstract extends AbstractClass, > = ( Class< - Omit, keyof Abstract>, + Omit< + InstanceType, + keyof InstanceType + >, + ConstructorParameters > & - Omit, keyof StaticAbstract | "_tag"> + Omit< + StaticMembers, + keyof StaticMembers | "_tag" + > ) @@ -130,7 +132,12 @@ export class TraitBuilder< this.traitSuperExpression, this.traitAbstract, this.traitStaticAbstract, - apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass, + apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass< + ImplClassWithAbstract, + TraitClass< + Trait + > + >, ) } diff --git a/src/tests.ts b/src/tests.ts index eb3f498..117a19a 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -87,3 +87,20 @@ class User extends exp.extends implements Implements { } console.log(new User()) + + +// class Test1 { +// prop1: string = "ouient" +// prop2: bigint = 1n +// } + +// class Test2 extends Test1 { +// readonly prop1 = "juif" +// prop3: number = 69 +// } + +// type PureKeys = { +// [K in keyof T]: K extends keyof U ? T[K] extends U[K] ? never : K : K; +// }[keyof T] + +// type T = PureKeys -- 2.49.1 From e5e8b7fad751b0920c99e555670356272868c770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 17 Feb 2024 04:11:17 +0100 Subject: [PATCH 33/68] Pure TS implementation attempt --- src/TraitBuilder.ts | 28 ++++++++++++++++++++-------- src/tests.ts | 28 +++++++++++++++++++++++++--- src/util/extend.ts | 18 ++++++++++++++++-- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 3663194..a576ecd 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -2,10 +2,16 @@ import { Pipe, Tuples } from "hotscript" import { AbstractClass, Class } from "type-fest" import { Trait, TraitClass, TraitConcreteClass } from "./Trait" import { TraitExpression } from "./TraitExpression" -import { ExtendFn, SimplifyFn, StaticMembers } from "./util" +import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembers } from "./util" -type ExtendAbstractSuper = ( +export type ExtendAbstractSuper< + SuperExpression extends TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + Abstract extends object, +> = ( Pipe, @@ -13,6 +19,12 @@ type ExtendAbstractSuper = ( ExtendFn, SimplifyFn, ]> + // ExtendPlain<[ + // ...Trait.OwnAbstract< + // TraitExpression.Traits[number] + // >, + // Abstract, + // ]> ) type ExtendStaticAbstractSuper = ( @@ -30,19 +42,20 @@ type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" type RemoveAbstractFromImplClass< ImplClassWithAbstract extends AbstractClass, - Abstract extends AbstractClass, + Abstract extends object, + StaticAbstract extends object, > = ( Class< Omit< InstanceType, - keyof InstanceType + keyof Abstract >, ConstructorParameters > & Omit< StaticMembers, - keyof StaticMembers | "_tag" + keyof StaticAbstract | "_tag" > ) @@ -134,9 +147,8 @@ export class TraitBuilder< this.traitStaticAbstract, apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass< ImplClassWithAbstract, - TraitClass< - Trait - > + ExtendAbstractSuper, + ExtendStaticAbstractSuper >, ) } diff --git a/src/tests.ts b/src/tests.ts index 117a19a..eea1d3a 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,7 +1,25 @@ -import { TraitClass } from "./Trait" +import { Trait, TraitClass } from "./Trait" import { trait } from "./TraitBuilder" -import { Implements, ImplementsStatic } from "./TraitExpression" +import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" +import { ExtendPlain } from "./util" + + +type ExtendAbstractSuper< + SuperExpression extends TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + Abstract extends object, +> = ( + // ExtendPlain<[ + // ...Trait.OwnAbstract< + // TraitExpression.Traits[number] + // >, + // Abstract, + // ]> + TraitExpression.Traits[number] +) const PrintsHelloOnNew = trait @@ -48,7 +66,7 @@ const StatefulSubscription = trait type StatefulSubscriptionClass = TraitClass const ActiveStatefulSubscription = expression - .expresses(StatefulSubscription) + .expresses(PrintsHelloOnNew, StatefulSubscription) .build() .subtrait() .extendAbstract(Super => class extends Super { @@ -58,6 +76,10 @@ const ActiveStatefulSubscription = expression .build() type ActiveStatefulSubscriptionClass = TraitClass +type Test = ExtendAbstractSuper< + Trait.OwnSuperExpression, + Trait.OwnAbstract +> class TestSuperclass { diff --git a/src/util/extend.ts b/src/util/extend.ts index d675de5..0b162d1 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -12,7 +12,21 @@ interface ExtendReducerFn extends Fn { } export type ExtendFn = Tuples.Reduce -export type Extend = Call +export type Extend = Call + + +export type ExtendPlain = ( + T extends [infer Super, infer Self, ...infer Rest] + ? Pick> extends Pick> + ? ExtendPlain<[ + Omit> & Self, + ...Rest, + ]> + : never + : T extends [infer Self] + ? Self + : void +) export type ExtendableFn = ComposeLeft<[ @@ -22,4 +36,4 @@ export type ExtendableFn = ComposeLeft<[ Match.With, ]> ]> -export type Extendable = Call +export type Extendable = Call -- 2.49.1 From 2fa71aaf37dafc0fb63dd22cba1cc3f53b379c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 17 Feb 2024 05:13:38 +0100 Subject: [PATCH 34/68] TraitBuilder work --- src/TraitBuilder.ts | 58 ++++++++++++++++++++++----------------------- src/tests.ts | 52 ++++++++++------------------------------ 2 files changed, 40 insertions(+), 70 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index a576ecd..5f1d124 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,42 +1,40 @@ -import { Pipe, Tuples } from "hotscript" -import { AbstractClass, Class } from "type-fest" +import { AbstractClass, Class, Simplify } from "type-fest" import { Trait, TraitClass, TraitConcreteClass } from "./Trait" import { TraitExpression } from "./TraitExpression" -import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembers } from "./util" +import { ExtendPlain, StaticMembers } from "./util" -export type ExtendAbstractSuper< - SuperExpression extends TraitExpression< - typeof TraitExpression.NullSuperclass, - Trait[] - >, - Abstract extends object, -> = ( - Pipe, - Tuples.Append, - ExtendFn, - SimplifyFn, - ]> - // ExtendPlain<[ - // ...Trait.OwnAbstract< - // TraitExpression.Traits[number] - // >, - // Abstract, - // ]> +type ExtendAbstractSuper = ( + Simplify< + ExtendPlain<[ + ...MapTraitsToOwnAbstract< + TraitExpression.Traits + >, + Abstract, + ]> + > ) +type MapTraitsToOwnAbstract = { + [K in keyof T]: Trait.OwnAbstract +} + + type ExtendStaticAbstractSuper = ( - Pipe, - Tuples.Append, - ExtendFn, - SimplifyFn, - ]> + Simplify< + ExtendPlain<[ + ...MapTraitsToOwnStaticAbstract< + TraitExpression.Traits + >, + StaticAbstract, + ]> + > ) +type MapTraitsToOwnStaticAbstract = { + [K in keyof T]: Trait.OwnStaticAbstract +} + type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" diff --git a/src/tests.ts b/src/tests.ts index eea1d3a..776bf46 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,25 +1,7 @@ -import { Trait, TraitClass } from "./Trait" +import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" -import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" +import { Implements, ImplementsStatic } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" -import { ExtendPlain } from "./util" - - -type ExtendAbstractSuper< - SuperExpression extends TraitExpression< - typeof TraitExpression.NullSuperclass, - Trait[] - >, - Abstract extends object, -> = ( - // ExtendPlain<[ - // ...Trait.OwnAbstract< - // TraitExpression.Traits[number] - // >, - // Abstract, - // ]> - TraitExpression.Traits[number] -) const PrintsHelloOnNew = trait @@ -53,7 +35,7 @@ const StatefulSubscription = trait // { _tag: "expired", expiredSince: Date } // ) // }>() - .extendAbstract(Super => class extends Super { + .extendAbstract(Super => class StatefulSubscriptionAbstract extends Super { readonly isStatefulSubscription!: true readonly status!: ( { _tag: "awaitingPayment" } | @@ -66,7 +48,7 @@ const StatefulSubscription = trait type StatefulSubscriptionClass = TraitClass const ActiveStatefulSubscription = expression - .expresses(PrintsHelloOnNew, StatefulSubscription) + .expresses(StatefulSubscription) .build() .subtrait() .extendAbstract(Super => class extends Super { @@ -76,11 +58,6 @@ const ActiveStatefulSubscription = expression .build() type ActiveStatefulSubscriptionClass = TraitClass -type Test = ExtendAbstractSuper< - Trait.OwnSuperExpression, - Trait.OwnAbstract -> - class TestSuperclass { // id: number = 69 @@ -111,18 +88,13 @@ class User extends exp.extends implements Implements { console.log(new User()) -// class Test1 { -// prop1: string = "ouient" -// prop2: bigint = 1n -// } +type MyTuple = [ + { values: { gneugneu: string } }, + { values: { ataoy: "issou" } }, +] -// class Test2 extends Test1 { -// readonly prop1 = "juif" -// prop3: number = 69 -// } +type MapToValues = { + [K in keyof T]: T[K]["values"] +} -// type PureKeys = { -// [K in keyof T]: K extends keyof U ? T[K] extends U[K] ? never : K : K; -// }[keyof T] - -// type T = PureKeys +type T = MapToValues -- 2.49.1 From 04146f6c6963b97ee924420189873549ab19ba82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 17 Feb 2024 17:12:46 +0100 Subject: [PATCH 35/68] SubtraitAbstract --- src/TraitExpression.ts | 29 ++++++++++++++++++++++++++--- src/util/extend.ts | 20 ++++++++++++-------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index b631dbc..d63eb89 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -2,7 +2,30 @@ import { Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class } from "type-fest" import { Trait } from "./Trait" import { TraitBuilder } from "./TraitBuilder" -import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util" +import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembersFn } from "./util" + + +type SubtraitAbstract = ( + ExtendPlain< + MapTraitsToOwnAbstract< + TraitExpression.Traits + > + > +) +type MapTraitsToOwnAbstract = { + [K in keyof T]: Trait.OwnAbstract +} + +type SubtraitStaticAbstract = ( + ExtendPlain< + MapTraitsToOwnStaticAbstract< + TraitExpression.Traits + > + > +) +type MapTraitsToOwnStaticAbstract = { + [K in keyof T]: Trait.OwnStaticAbstract +} export class TraitExpression< @@ -49,8 +72,8 @@ export class TraitExpression< ) { return new TraitBuilder( this, - {}, - {}, + {} as SubtraitAbstract, + {} as SubtraitStaticAbstract, Super => class extends Super {}, ) } diff --git a/src/util/extend.ts b/src/util/extend.ts index 0b162d1..2592f09 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -15,17 +15,21 @@ export type ExtendFn = Tuples.Reduce export type Extend = Call -export type ExtendPlain = ( +export type ExtendPlain = ( T extends [infer Super, infer Self, ...infer Rest] - ? Pick> extends Pick> - ? ExtendPlain<[ - Omit> & Self, - ...Rest, - ]> + ? Rest extends object[] + ? Pick> extends Pick> + ? ExtendPlain<[ + Omit> & Self, + ...Rest, + ]> + : never : never : T extends [infer Self] - ? Self - : void + ? Self extends object + ? Self + : never + : {} ) -- 2.49.1 From c1f48b9bb25b46e73d1f2139b0e9528d66746324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 17 Feb 2024 21:23:08 +0100 Subject: [PATCH 36/68] TraitBuilder work --- src/TraitBuilder.ts | 40 +++++++--------------------------------- src/TraitExpression.ts | 6 +++--- src/tests.ts | 36 +++++++++--------------------------- 3 files changed, 19 insertions(+), 63 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 5f1d124..28b242f 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -74,50 +74,24 @@ export class TraitBuilder< private readonly traitApply: (Super: AbstractClass) => ImplClass, ) {} - abstract>() { + abstract( + _: (Super: AbstractClass) => AbstractClass + ) { return new TraitBuilder( this.traitSuperExpression, - {} as A, + {} as Simplify, this.traitStaticAbstract, this.traitApply, ) } - extendAbstract>( - _: ( - Super: AbstractClass< - ExtendAbstractSuper - > - ) => AbstractClass - ) { - return new TraitBuilder( - this.traitSuperExpression, - {} as A, - this.traitStaticAbstract, - this.traitApply, - ) - } - - staticAbstract>() { - return new TraitBuilder( - this.traitSuperExpression, - this.traitAbstract, - {} as A, - this.traitApply, - ) - } - - extendStaticAbstract>( - _: ( - Super: AbstractClass< - ExtendStaticAbstractSuper - > - ) => AbstractClass + staticAbstract( + _: (Super: AbstractClass) => AbstractClass ) { return new TraitBuilder( this.traitSuperExpression, this.traitAbstract, - {} as A, + {} as Simplify, this.traitApply, ) } diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index d63eb89..d79b0c3 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,5 +1,5 @@ import { Fn, Pipe, Tuples } from "hotscript" -import { AbstractClass, Class } from "type-fest" +import { AbstractClass, Class, Simplify } from "type-fest" import { Trait } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembersFn } from "./util" @@ -72,8 +72,8 @@ export class TraitExpression< ) { return new TraitBuilder( this, - {} as SubtraitAbstract, - {} as SubtraitStaticAbstract, + {} as Simplify>, + {} as Simplify>, Super => class extends Super {}, ) } diff --git a/src/tests.ts b/src/tests.ts index 776bf46..bc0ad49 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -18,7 +18,9 @@ const PrintsHelloOnNew = trait type PrintsHelloOnNewClass = TraitClass const Identifiable = () => trait - .abstract<{ readonly id: ID }>() + .abstract(Super => class extends Super { + declare readonly id: ID + }) .implement(Super => class Identifiable extends Super { equals(el: Identifiable) { return this.id === el.id @@ -27,17 +29,9 @@ const Identifiable = () => trait .build() const StatefulSubscription = trait - // .abstract<{ - // readonly isStatefulSubscription: true - // readonly status: ( - // { _tag: "awaitingPayment" } | - // { _tag: "active", activeSince: Date, expiresAt?: Date } | - // { _tag: "expired", expiredSince: Date } - // ) - // }>() - .extendAbstract(Super => class StatefulSubscriptionAbstract extends Super { - readonly isStatefulSubscription!: true - readonly status!: ( + .abstract(Super => class extends Super { + declare readonly isStatefulSubscription: true + declare readonly status: ( { _tag: "awaitingPayment" } | { _tag: "active", activeSince: Date, expiresAt?: Date } | { _tag: "expired", expiredSince: Date } @@ -51,9 +45,9 @@ const ActiveStatefulSubscription = expression .expresses(StatefulSubscription) .build() .subtrait() - .extendAbstract(Super => class extends Super { - readonly isActiveStatefulSubscription!: true - readonly status!: { _tag: "active", activeSince: Date, expiresAt?: Date } + .abstract(Super => class extends Super { + declare readonly isActiveStatefulSubscription: true + declare readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date } }) .build() @@ -86,15 +80,3 @@ class User extends exp.extends implements Implements { } console.log(new User()) - - -type MyTuple = [ - { values: { gneugneu: string } }, - { values: { ataoy: "issou" } }, -] - -type MapToValues = { - [K in keyof T]: T[K]["values"] -} - -type T = MapToValues -- 2.49.1 From 3667e69d693a1c84b2fa8e5e114821cc38ff77f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 02:55:22 +0100 Subject: [PATCH 37/68] Slowly getting insane --- src/TraitBuilder.ts | 92 ++++++++++++++++++++++++++++++++------------- src/tests.ts | 20 +++++++++- 2 files changed, 84 insertions(+), 28 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 28b242f..30ad5f2 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -4,35 +4,74 @@ import { TraitExpression } from "./TraitExpression" import { ExtendPlain, StaticMembers } from "./util" -type ExtendAbstractSuper = ( - Simplify< +// type ExtendAbstractSuper = ( +// Simplify< +// ExtendPlain<[ +// ...MapTraitsToOwnAbstract< +// TraitExpression.Traits +// >, +// Abstract, +// ]> +// > +// ) +// type MapTraitsToOwnAbstract = { +// [K in keyof T]: Trait.OwnAbstract +// } + +// type ExtendStaticAbstractSuper, StaticAbstract extends object> = ( +// Simplify< +// ExtendPlain<[ +// ...MapTraitsToOwnStaticAbstract< +// TraitExpression.Traits +// >, +// StaticAbstract, +// ]> +// > +// ) +// type MapTraitsToOwnStaticAbstract = { +// [K in keyof T]: Trait.OwnStaticAbstract +// } + +type ImplSuper< + SuperExpression extends TraitExpression< + any, + Trait[] + >, + Abstract extends object, + StaticAbstract extends object, +> = ( + AbstractClass< ExtendPlain<[ - ...MapTraitsToOwnAbstract< + ...MapTraitsToOwnImplInstance< TraitExpression.Traits >, Abstract, ]> - > -) - -type MapTraitsToOwnAbstract = { - [K in keyof T]: Trait.OwnAbstract -} - - -type ExtendStaticAbstractSuper = ( - Simplify< - ExtendPlain<[ - ...MapTraitsToOwnStaticAbstract< + > & + // ExtendPlain<[ + // ...MapTraitsToOwnImplStaticMembers< + // TraitExpression.Traits + // >, + // StaticAbstract, + // ]> + ExtendPlain< + MapStaticMembers< + MapTraitsToOwnImplStaticMembers< TraitExpression.Traits - >, - StaticAbstract, - ]> + > + > > ) - -type MapTraitsToOwnStaticAbstract = { - [K in keyof T]: Trait.OwnStaticAbstract +type MapTraitsToOwnImplInstance = { + [K in keyof T]: InstanceType> +} +type MapTraitsToOwnImplStaticMembers = { + [K in keyof T]: Trait.OwnImplClass +} +type MapStaticMembers[]> = { + [TupleK in keyof Tuple]: { + [ClassK in keyof Tuple[TupleK]]: Tuple[TupleK][ClassK] + } } @@ -117,11 +156,12 @@ export class TraitBuilder< this.traitSuperExpression, this.traitAbstract, this.traitStaticAbstract, - apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass< - ImplClassWithAbstract, - ExtendAbstractSuper, - ExtendStaticAbstractSuper - >, + // apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass< + // ImplClassWithAbstract, + // ExtendAbstractSuper, + // ExtendStaticAbstractSuper + // >, + apply as unknown as (Super: AbstractClass) => ImplClassWithAbstract, ) } diff --git a/src/tests.ts b/src/tests.ts index bc0ad49..99f2d9c 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,7 +1,8 @@ -import { TraitClass } from "./Trait" +import { Trait, TraitClass } from "./Trait" import { trait } from "./TraitBuilder" -import { Implements, ImplementsStatic } from "./TraitExpression" +import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" +import { ExtendPlain } from "./util" const PrintsHelloOnNew = trait @@ -80,3 +81,18 @@ class User extends exp.extends implements Implements { } console.log(new User()) + + +type ExpectsObjectArray = T + +type Maps = { + [K in keyof T]: T[K] +} + +type MapTraits> = ( + ExpectsObjectArray< + Maps< + + > + > +) -- 2.49.1 From 45ec2dd0e399799a4352835bfd15b47fc76735fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 03:33:36 +0100 Subject: [PATCH 38/68] Tests --- src/tests.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tests.ts b/src/tests.ts index 99f2d9c..7d26ae9 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,8 +1,9 @@ +import { AbstractClass } from "type-fest" import { Trait, TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" -import { ExtendPlain } from "./util" +import { ExtendPlain, StaticMembers } from "./util" const PrintsHelloOnNew = trait @@ -85,14 +86,17 @@ console.log(new User()) type ExpectsObjectArray = T -type Maps = { - [K in keyof T]: T[K] +type MapStaticMembers = { + [K in keyof T]: StaticMembers } -type MapTraits> = ( +type MapClasses[]> = ( ExpectsObjectArray< - Maps< - + MapStaticMembers< + Classes > > ) + + +type Output = MapClasses<[typeof User]> -- 2.49.1 From 517792b1c2c08798796df4e7635a4c365a655713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 04:10:20 +0100 Subject: [PATCH 39/68] Found working approach --- src/TraitBuilder.ts | 6 ++---- src/tests.ts | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 30ad5f2..b92658d 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -68,10 +68,8 @@ type MapTraitsToOwnImplInstance = { type MapTraitsToOwnImplStaticMembers = { [K in keyof T]: Trait.OwnImplClass } -type MapStaticMembers[]> = { - [TupleK in keyof Tuple]: { - [ClassK in keyof Tuple[TupleK]]: Tuple[TupleK][ClassK] - } +type MapStaticMembers[]> = { + [K in keyof T]: StaticMembers } diff --git a/src/tests.ts b/src/tests.ts index 7d26ae9..8c2207d 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -84,19 +84,27 @@ class User extends exp.extends implements Implements { console.log(new User()) -type ExpectsObjectArray = T +type ExpectObjectArray = T + +type MapOwnImplClass = { + [K in keyof T]: Trait.OwnImplClass +} type MapStaticMembers = { [K in keyof T]: StaticMembers } -type MapClasses[]> = ( - ExpectsObjectArray< - MapStaticMembers< - Classes + +type MapClasses = ( + Exp extends TraitExpression + ? ExpectObjectArray< + MapStaticMembers< + MapOwnImplClass< + Traits + > + > > - > + : never ) - -type Output = MapClasses<[typeof User]> +type Output = MapClasses -- 2.49.1 From 2acee3f2a36d36af5daa19faba4d15074591020b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 04:59:47 +0100 Subject: [PATCH 40/68] Fixed TraitBuilder --- src/Trait.ts | 18 ++++++ src/TraitBuilder.ts | 135 ++++++++++++-------------------------------- src/tests.ts | 32 +---------- 3 files changed, 57 insertions(+), 128 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 3f2e39f..4ba2450 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -65,6 +65,10 @@ export namespace Trait { return: Trait.OwnImplInstance } + export type OwnImplStaticMembers = ( + StaticMembers> + ) + export type OwnClass = ( AbstractClass, any[]> & Extend<[ @@ -91,6 +95,20 @@ export namespace Trait { } } +export namespace Traits { + export type MapImplClass = { + [K in keyof T]: Trait.OwnImplClass + } + + export type MapImplInstance = { + [K in keyof T]: Trait.OwnImplInstance + } + + export type MapImplStaticMembers = { + [K in keyof T]: Trait.OwnImplStaticMembers + } +} + export type TraitClass> = ( AbstractClass, any[]> & diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index b92658d..4c95b0a 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,97 +1,25 @@ import { AbstractClass, Class, Simplify } from "type-fest" -import { Trait, TraitClass, TraitConcreteClass } from "./Trait" +import { Trait, Traits } from "./Trait" import { TraitExpression } from "./TraitExpression" import { ExtendPlain, StaticMembers } from "./util" -// type ExtendAbstractSuper = ( -// Simplify< -// ExtendPlain<[ -// ...MapTraitsToOwnAbstract< -// TraitExpression.Traits -// >, -// Abstract, -// ]> -// > -// ) -// type MapTraitsToOwnAbstract = { -// [K in keyof T]: Trait.OwnAbstract -// } - -// type ExtendStaticAbstractSuper, StaticAbstract extends object> = ( -// Simplify< -// ExtendPlain<[ -// ...MapTraitsToOwnStaticAbstract< -// TraitExpression.Traits -// >, -// StaticAbstract, -// ]> -// > -// ) -// type MapTraitsToOwnStaticAbstract = { -// [K in keyof T]: Trait.OwnStaticAbstract -// } - type ImplSuper< - SuperExpression extends TraitExpression< - any, - Trait[] - >, + Supertraits extends Trait[], Abstract extends object, StaticAbstract extends object, > = ( AbstractClass< ExtendPlain<[ - ...MapTraitsToOwnImplInstance< - TraitExpression.Traits - >, + ...Traits.MapImplInstance, Abstract, ]> > & - // ExtendPlain<[ - // ...MapTraitsToOwnImplStaticMembers< - // TraitExpression.Traits - // >, - // StaticAbstract, - // ]> - ExtendPlain< - MapStaticMembers< - MapTraitsToOwnImplStaticMembers< - TraitExpression.Traits - > - > - > -) -type MapTraitsToOwnImplInstance = { - [K in keyof T]: InstanceType> -} -type MapTraitsToOwnImplStaticMembers = { - [K in keyof T]: Trait.OwnImplClass -} -type MapStaticMembers[]> = { - [K in keyof T]: StaticMembers -} - - -type TraitApplierSuperTag = "@thilawyn/traitify-ts/Super" - -type RemoveAbstractFromImplClass< - ImplClassWithAbstract extends AbstractClass, - Abstract extends object, - StaticAbstract extends object, -> = ( - Class< - Omit< - InstanceType, - keyof Abstract - >, - - ConstructorParameters - > & - Omit< - StaticMembers, - keyof StaticAbstract | "_tag" - > + ExtendPlain<[ + ...Traits.MapImplStaticMembers, + StaticAbstract, + ]> & + { readonly _tag: "@thilawyn/traitify-ts/Super" } // TODO: replace with unique symbol? ) @@ -134,32 +62,43 @@ export class TraitBuilder< } implement< - ImplClassWithAbstract extends ( - TraitConcreteClass< - Trait - > & - { _tag: TraitApplierSuperTag } - ) + ImplClassWithAbstract extends ImplSuper< // TODO: use This instead? + TraitExpression.Traits, + Abstract, + StaticAbstract + > >( apply: ( - Super: ( - TraitClass< - Trait - > & - { _tag: TraitApplierSuperTag } - ) + Super: ImplSuper< + TraitExpression.Traits, + Abstract, + StaticAbstract + > ) => ImplClassWithAbstract ) { return new TraitBuilder( this.traitSuperExpression, this.traitAbstract, this.traitStaticAbstract, - // apply as unknown as (Super: AbstractClass) => RemoveAbstractFromImplClass< - // ImplClassWithAbstract, - // ExtendAbstractSuper, - // ExtendStaticAbstractSuper - // >, - apply as unknown as (Super: AbstractClass) => ImplClassWithAbstract, + + apply as unknown as (Super: AbstractClass) => ( + Class< + Simplify< + Omit< + InstanceType, + keyof Abstract + > + >, + + ConstructorParameters + > & + Simplify< + Omit< + StaticMembers, + keyof StaticAbstract | "_tag" + > + > + ), ) } diff --git a/src/tests.ts b/src/tests.ts index 8c2207d..bc0ad49 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,9 +1,7 @@ -import { AbstractClass } from "type-fest" -import { Trait, TraitClass } from "./Trait" +import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" -import { Implements, ImplementsStatic, TraitExpression } from "./TraitExpression" +import { Implements, ImplementsStatic } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" -import { ExtendPlain, StaticMembers } from "./util" const PrintsHelloOnNew = trait @@ -82,29 +80,3 @@ class User extends exp.extends implements Implements { } console.log(new User()) - - -type ExpectObjectArray = T - -type MapOwnImplClass = { - [K in keyof T]: Trait.OwnImplClass -} - -type MapStaticMembers = { - [K in keyof T]: StaticMembers -} - - -type MapClasses = ( - Exp extends TraitExpression - ? ExpectObjectArray< - MapStaticMembers< - MapOwnImplClass< - Traits - > - > - > - : never -) - -type Output = MapClasses -- 2.49.1 From a0369ef2e620a2e937344afcff59ba274735ba07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 05:01:06 +0100 Subject: [PATCH 41/68] Added TODO --- src/TraitBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 4c95b0a..420202c 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -82,7 +82,7 @@ export class TraitBuilder< this.traitStaticAbstract, apply as unknown as (Super: AbstractClass) => ( - Class< + Class< // TODO: use abstract class instead Simplify< Omit< InstanceType, -- 2.49.1 From 9524458c0fc791b7bb9275caf129c42284924d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 20:51:58 +0100 Subject: [PATCH 42/68] Trait work --- src/Trait.ts | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 4ba2450..16988cd 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,7 +1,7 @@ -import { Fn, Pipe, Tuples } from "hotscript" -import { AbstractClass, Class } from "type-fest" +import { Fn } from "hotscript" +import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { Extend, ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" +import { Extend, StaticMembers } from "./util" export class Trait< @@ -121,22 +121,19 @@ export type TraitConcreteClass> = ( ) export type TraitInstance> = ( - Pipe, - Tuples.Map, - ExtendFn, - SimplifyFn, - ]> + Simplify< + Extend<[ + Trait.OwnAbstract, + Trait.OwnImplInstance, + ]> + > ) export type TraitStaticMembers> = ( - Pipe, - Tuples.Map, - Tuples.Map, - ExtendFn, - SimplifyFn, - ]> + Simplify< + Extend<[ + Trait.OwnStaticAbstract, + StaticMembers>, + ]> + > ) -- 2.49.1 From 20554ec55a8b778218277a95cc9c7dacedbbb9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 21:44:19 +0100 Subject: [PATCH 43/68] Trait work --- src/Trait.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 16988cd..e8f5cfd 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,7 +1,7 @@ import { Fn } from "hotscript" import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { Extend, StaticMembers } from "./util" +import { Extend, ExtendPlain, StaticMembers } from "./util" export class Trait< @@ -96,16 +96,18 @@ export namespace Trait { } export namespace Traits { - export type MapImplClass = { + export type MapImplClass = { [K in keyof T]: Trait.OwnImplClass } - export type MapImplInstance = { + export type MapImplInstance = { [K in keyof T]: Trait.OwnImplInstance } - export type MapImplStaticMembers = { - [K in keyof T]: Trait.OwnImplStaticMembers + export type MapImplStaticMembers = { + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.OwnImplStaticMembers } } @@ -122,7 +124,7 @@ export type TraitConcreteClass> = ( export type TraitInstance> = ( Simplify< - Extend<[ + ExtendPlain<[ Trait.OwnAbstract, Trait.OwnImplInstance, ]> @@ -131,7 +133,7 @@ export type TraitInstance> = ( export type TraitStaticMembers> = ( Simplify< - Extend<[ + ExtendPlain<[ Trait.OwnStaticAbstract, StaticMembers>, ]> -- 2.49.1 From 40eaa80eb63058b447abf5eed42b524239a56363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 Feb 2024 22:06:33 +0100 Subject: [PATCH 44/68] TraitBuilder work --- src/Trait.ts | 8 ++++++-- src/TraitBuilder.ts | 21 ++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index e8f5cfd..2a2cfbe 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -97,11 +97,15 @@ export namespace Trait { export namespace Traits { export type MapImplClass = { - [K in keyof T]: Trait.OwnImplClass + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.OwnImplClass } export type MapImplInstance = { - [K in keyof T]: Trait.OwnImplInstance + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.OwnImplInstance } export type MapImplStaticMembers = { diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 420202c..1a68621 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -5,18 +5,25 @@ import { ExtendPlain, StaticMembers } from "./util" type ImplSuper< - Supertraits extends Trait[], + SuperExpression extends TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, Abstract extends object, StaticAbstract extends object, > = ( AbstractClass< ExtendPlain<[ - ...Traits.MapImplInstance, + ...Traits.MapImplInstance< + TraitExpression.Traits + >, Abstract, ]> > & ExtendPlain<[ - ...Traits.MapImplStaticMembers, + ...Traits.MapImplStaticMembers< + TraitExpression.Traits + >, StaticAbstract, ]> & { readonly _tag: "@thilawyn/traitify-ts/Super" } // TODO: replace with unique symbol? @@ -63,17 +70,13 @@ export class TraitBuilder< implement< ImplClassWithAbstract extends ImplSuper< // TODO: use This instead? - TraitExpression.Traits, + SuperExpression, Abstract, StaticAbstract > >( apply: ( - Super: ImplSuper< - TraitExpression.Traits, - Abstract, - StaticAbstract - > + Super: ImplSuper ) => ImplClassWithAbstract ) { return new TraitBuilder( -- 2.49.1 From 34c91707ae610b7b9e4ecaf8732654ae9ca13cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 01:11:22 +0100 Subject: [PATCH 45/68] TraitExpression work --- src/Trait.ts | 14 +++++++++- src/TraitBuilder.ts | 6 ++--- src/TraitExpression.ts | 61 +++++++++++++++++++----------------------- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 2a2cfbe..f340371 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -11,7 +11,7 @@ export class Trait< >, Abstract extends object, StaticAbstract extends object, - ImplClass extends Class, + ImplClass extends AbstractClass, > { constructor( readonly superExpression: SuperExpression, @@ -96,6 +96,18 @@ export namespace Trait { } export namespace Traits { + export type MapAbstract = { + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.OwnAbstract + } + + export type MapStaticAbstract = { + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.OwnStaticAbstract + } + export type MapImplClass = { [K in keyof T]: K extends keyof [] ? T[K] diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 1a68621..c54c34c 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,4 +1,4 @@ -import { AbstractClass, Class, Simplify } from "type-fest" +import { AbstractClass, Simplify } from "type-fest" import { Trait, Traits } from "./Trait" import { TraitExpression } from "./TraitExpression" import { ExtendPlain, StaticMembers } from "./util" @@ -37,7 +37,7 @@ export class TraitBuilder< >, Abstract extends object, StaticAbstract extends object, - ImplClass extends Class, + ImplClass extends AbstractClass, > { constructor( private readonly traitSuperExpression: SuperExpression, @@ -85,7 +85,7 @@ export class TraitBuilder< this.traitStaticAbstract, apply as unknown as (Super: AbstractClass) => ( - Class< // TODO: use abstract class instead + AbstractClass< Simplify< Omit< InstanceType, diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index d79b0c3..46e912a 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,45 +1,22 @@ import { Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class, Simplify } from "type-fest" -import { Trait } from "./Trait" +import { Trait, Traits } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembersFn } from "./util" -type SubtraitAbstract = ( - ExtendPlain< - MapTraitsToOwnAbstract< - TraitExpression.Traits - > - > -) -type MapTraitsToOwnAbstract = { - [K in keyof T]: Trait.OwnAbstract -} - -type SubtraitStaticAbstract = ( - ExtendPlain< - MapTraitsToOwnStaticAbstract< - TraitExpression.Traits - > - > -) -type MapTraitsToOwnStaticAbstract = { - [K in keyof T]: Trait.OwnStaticAbstract -} - - export class TraitExpression< - Superclass extends AbstractClass, - const Traits extends Trait[], + Superclass extends AbstractClass, + const T extends Trait[], > { constructor( readonly superclass: Superclass, - readonly traits: Traits, + readonly traits: T, ) {} get extends(): ( AbstractClass< - Pipe, // Map all the traits to the instance of their implementation class Tuples.Prepend>, // Add the instance of the superclass at the top of the list ExtendFn, // Reduce to a single instance that extends all the instances in the list @@ -49,7 +26,7 @@ export class TraitExpression< ConstructorParameters > & - Pipe, // Map all the traits to their implementation class Tuples.Prepend, // Add the superclass at the top of the list Tuples.Map, // Map all the classes to an object containing their static members @@ -70,11 +47,29 @@ export class TraitExpression< >( this: This ) { - return new TraitBuilder( + return new TraitBuilder< + This, + Simplify< + ExtendPlain> + >, + Simplify< + ExtendPlain> + >, + ( + AbstractClass< + Simplify< + ExtendPlain> + > + > & + Simplify< + ExtendPlain> + > + ) + >( this, - {} as Simplify>, - {} as Simplify>, - Super => class extends Super {}, + {} as any, + {} as any, + Super => class extends Super {} as any, ) } } -- 2.49.1 From 3c470a63f2bf174e6cc13d6fa44e0c2e9ceca789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 01:40:24 +0100 Subject: [PATCH 46/68] Fixed TraitBuilder --- src/TraitBuilder.ts | 64 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index c54c34c..6d61efc 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,32 +1,34 @@ import { AbstractClass, Simplify } from "type-fest" -import { Trait, Traits } from "./Trait" +import { Trait } from "./Trait" import { TraitExpression } from "./TraitExpression" import { ExtendPlain, StaticMembers } from "./util" -type ImplSuper< - SuperExpression extends TraitExpression< - typeof TraitExpression.NullSuperclass, - Trait[] - >, - Abstract extends object, - StaticAbstract extends object, -> = ( - AbstractClass< - ExtendPlain<[ - ...Traits.MapImplInstance< - TraitExpression.Traits - >, - Abstract, - ]> - > & - ExtendPlain<[ - ...Traits.MapImplStaticMembers< - TraitExpression.Traits - >, - StaticAbstract, - ]> & - { readonly _tag: "@thilawyn/traitify-ts/Super" } // TODO: replace with unique symbol? +type ImplSuper = ( + This extends TraitBuilder< + any, + infer Abstract, + infer StaticAbstract, + infer ImplClass + > + ? ( + AbstractClass< + Simplify< + ExtendPlain<[ + Abstract, + InstanceType, + ]> + > + > & + Simplify< + ExtendPlain<[ + StaticAbstract, + StaticMembers, + ]> + > & + { readonly _tag: "@thilawyn/traitify-ts/Super" } // TODO: replace with unique symbol? + ) + : never ) @@ -69,15 +71,9 @@ export class TraitBuilder< } implement< - ImplClassWithAbstract extends ImplSuper< // TODO: use This instead? - SuperExpression, - Abstract, - StaticAbstract - > + ImplClassWithAbstract extends ImplSuper >( - apply: ( - Super: ImplSuper - ) => ImplClassWithAbstract + apply: (Super: ImplSuper) => ImplClassWithAbstract ) { return new TraitBuilder( this.traitSuperExpression, @@ -91,9 +87,7 @@ export class TraitBuilder< InstanceType, keyof Abstract > - >, - - ConstructorParameters + > > & Simplify< Omit< -- 2.49.1 From 2e716e7f96de30bfadbf60fb20dc9b20cacab1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 02:48:21 +0100 Subject: [PATCH 47/68] TraitExpression work --- src/Trait.ts | 18 -------- src/TraitExpression.ts | 97 +++++++++++++++++++++++++++--------------- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index f340371..886fb77 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -69,24 +69,6 @@ export namespace Trait { StaticMembers> ) - export type OwnClass = ( - AbstractClass, any[]> & - Extend<[ - Trait.OwnStaticAbstract, - StaticMembers>, - ]> - ) - export interface OwnClassFn extends Fn { - return: Trait.OwnClass - } - - export type OwnInstance = ( - Extend<[Trait.OwnAbstract, Trait.OwnImplInstance]> - ) - export interface OwnInstanceFn extends Fn { - return: Trait.OwnInstance - } - export type Supertraits = ( TraitExpression.Traits> ) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 46e912a..3c3a5fb 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,6 +1,6 @@ import { Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class, Simplify } from "type-fest" -import { Trait, Traits } from "./Trait" +import { Trait, TraitInstance, Traits } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembersFn } from "./util" @@ -49,22 +49,22 @@ export class TraitExpression< ) { return new TraitBuilder< This, + Simplify< ExtendPlain> >, Simplify< ExtendPlain> >, - ( - AbstractClass< - Simplify< - ExtendPlain> - > - > & + + AbstractClass< Simplify< - ExtendPlain> + ExtendPlain> > - ) + > & + Simplify< + ExtendPlain> + > >( this, {} as any, @@ -100,26 +100,34 @@ export namespace TraitExpression { } -export type Implements> = ( - Pipe, - ExtendFn, - SimplifyFn, - ]> +export type Implements< + Exp extends TraitExpression[]> +> = ( + Simplify< + ExtendPlain< + Traits.MapAbstract< + TraitExpression.Traits + > + > + > ) -export type ImplementsStatic> = ( - Pipe, - ExtendFn, - SimplifyFn, - ]> +export type ImplementsStatic< + Exp extends TraitExpression[]> +> = ( + Simplify< + ExtendPlain< + Traits.MapStaticAbstract< + TraitExpression.Traits + > + > + > ) -export type TraitExpressionClass> = ( +export type TraitExpressionClass< + Exp extends TraitExpression[]> +> = ( AbstractClass< TraitExpressionInstance, ConstructorParameters> @@ -127,7 +135,9 @@ export type TraitExpressionClass> = ( TraitExpressionStaticMembers ) -export type TraitExpressionConcreteClass> = ( +export type TraitExpressionConcreteClass< + Exp extends TraitExpression[]> +> = ( Class< TraitExpressionInstance, ConstructorParameters> @@ -135,18 +145,35 @@ export type TraitExpressionConcreteClass> TraitExpressionStaticMembers ) -export type TraitExpressionInstance> = ( - Pipe, [ - Tuples.Map, // Map all the traits to their instance representation - Tuples.Prepend< // Add the instance of the superclass at the top of the list - InstanceType> - >, - ExtendFn, // Reduce to a single object that extends all the objects in the list - SimplifyFn, // Make readable for IDEs - ]> +export type TraitExpressionInstance< + Exp extends TraitExpression[]> +> = ( + // Pipe, [ + // Tuples.Map, // Map all the traits to their instance representation + // Tuples.Prepend< // Add the instance of the superclass at the top of the list + // InstanceType> + // >, + // ExtendFn, // Reduce to a single object that extends all the objects in the list + // SimplifyFn, // Make readable for IDEs + // ]> + Simplify< + ExtendPlain<[ + InstanceType>, + ...MapTraitsInstance< + TraitExpression.Traits + >, + ]> + > ) +type MapTraitsInstance[]> = { + [K in keyof T]: K extends keyof [] + ? T[K] + : TraitInstance +} -export type TraitExpressionStaticMembers> = ( +export type TraitExpressionStaticMembers< + Exp extends TraitExpression[]> +> = ( Pipe, [ Tuples.Map, // Map all the traits to their class representation Tuples.Prepend>, // Add the superclass at the top of the list -- 2.49.1 From 4ba0a190377738558d20adfc0ee8177ce7c6e413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 03:57:23 +0100 Subject: [PATCH 48/68] TraitExpression work --- src/TraitExpression.ts | 42 ++++++++++++++++++++---------------------- src/tests.ts | 3 ++- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 3c3a5fb..e789b05 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,8 +1,8 @@ import { Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class, Simplify } from "type-fest" -import { Trait, TraitInstance, Traits } from "./Trait" +import { Trait, TraitInstance, TraitStaticMembers, Traits } from "./Trait" import { TraitBuilder } from "./TraitBuilder" -import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembersFn } from "./util" +import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" export class TraitExpression< @@ -148,37 +148,35 @@ export type TraitExpressionConcreteClass< export type TraitExpressionInstance< Exp extends TraitExpression[]> > = ( - // Pipe, [ - // Tuples.Map, // Map all the traits to their instance representation - // Tuples.Prepend< // Add the instance of the superclass at the top of the list - // InstanceType> - // >, - // ExtendFn, // Reduce to a single object that extends all the objects in the list - // SimplifyFn, // Make readable for IDEs - // ]> Simplify< ExtendPlain<[ InstanceType>, - ...MapTraitsInstance< - TraitExpression.Traits - >, + ...MapTraitsInstance>, ]> > ) -type MapTraitsInstance[]> = { +type MapTraitsInstance = { [K in keyof T]: K extends keyof [] ? T[K] - : TraitInstance + : T[K] extends Trait + ? TraitInstance + : never } export type TraitExpressionStaticMembers< Exp extends TraitExpression[]> > = ( - Pipe, [ - Tuples.Map, // Map all the traits to their class representation - Tuples.Prepend>, // Add the superclass at the top of the list - Tuples.Map, // Map all the classes to an object containing their static members - ExtendFn, // Reduce to a single object that extends all the objects in the list - SimplifyFn, // Make readable for IDEs - ]> + Simplify< + ExtendPlain<[ + StaticMembers>, + ...MapTraitsStaticMembers>, + ]> + > ) +type MapTraitsStaticMembers = { + [K in keyof T]: K extends keyof [] + ? T[K] + : T[K] extends Trait + ? TraitStaticMembers + : never +} diff --git a/src/tests.ts b/src/tests.ts index bc0ad49..631b011 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,6 +1,6 @@ import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" -import { Implements, ImplementsStatic } from "./TraitExpression" +import { Implements, ImplementsStatic, TraitExpressionClass } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" @@ -70,6 +70,7 @@ const exp = expression type Abs = Implements type AbsStatic = ImplementsStatic +type ExpClass = TraitExpressionClass @exp.implementsStatic class User extends exp.extends implements Implements { -- 2.49.1 From ec825373802d543408c865900a7a3b0efdfbaab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 17:07:28 +0100 Subject: [PATCH 49/68] Fixed TraitExpression --- src/TraitExpression.ts | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index e789b05..1a1c4c9 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,8 +1,7 @@ -import { Fn, Pipe, Tuples } from "hotscript" import { AbstractClass, Class, Simplify } from "type-fest" import { Trait, TraitInstance, TraitStaticMembers, Traits } from "./Trait" import { TraitBuilder } from "./TraitBuilder" -import { ExtendFn, ExtendPlain, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" +import { ExtendPlain, StaticMembers } from "./util" export class TraitExpression< @@ -16,23 +15,22 @@ export class TraitExpression< get extends(): ( AbstractClass< - Pipe, // Map all the traits to the instance of their implementation class - Tuples.Prepend>, // Add the instance of the superclass at the top of the list - ExtendFn, // Reduce to a single instance that extends all the instances in the list - SimplifyFn, // Make readable for IDEs - ]>, + Simplify< + ExtendPlain<[ + InstanceType, + ...Traits.MapImplInstance, + ]> + >, ConstructorParameters > & - Pipe, // Map all the traits to their implementation class - Tuples.Prepend, // Add the superclass at the top of the list - Tuples.Map, // Map all the classes to an object containing their static members - ExtendFn, // Reduce to a single object that extends all the objects in the list - SimplifyFn, // Make readable for IDEs - ]> + Simplify< + ExtendPlain<[ + StaticMembers, + ...Traits.MapImplStaticMembers, + ]> + > ) { return this.traits.reduce( (previous, trait) => trait.apply(previous), @@ -85,18 +83,12 @@ export namespace TraitExpression { ? Superclass : never ) - export interface SuperclassFn extends Fn { - return: TraitExpression.Superclass - } export type Traits = ( T extends TraitExpression ? Traits : never ) - export interface TraitsFn extends Fn { - return: TraitExpression.Traits - } } -- 2.49.1 From 7c4e754b24404304a5a6865323533acd5abd7d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 17:26:44 +0100 Subject: [PATCH 50/68] Trait refactoring --- src/Trait.ts | 59 ++++++++++++++---------------------------- src/TraitExpression.ts | 24 ++++++++--------- 2 files changed, 32 insertions(+), 51 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 886fb77..4bff053 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,7 +1,6 @@ -import { Fn } from "hotscript" import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { Extend, ExtendPlain, StaticMembers } from "./util" +import { ExtendPlain, StaticMembers } from "./util" export class Trait< @@ -22,90 +21,72 @@ export class Trait< } export namespace Trait { - export type OwnSuperExpression = ( + export type SuperExpression = ( T extends Trait ? SuperExpression : never ) - export interface OwnSuperExpressionFn extends Fn { - return: Trait.OwnSuperExpression - } - export type OwnAbstract = ( + export type Abstract = ( T extends Trait ? Abstract : never ) - export interface OwnAbstractFn extends Fn { - return: Trait.OwnAbstract - } - export type OwnStaticAbstract = ( + export type StaticAbstract = ( T extends Trait ? StaticAbstract : never ) - export interface OwnStaticAbstractFn extends Fn { - return: Trait.OwnStaticAbstract - } - export type OwnImplClass = ( + export type ImplClass = ( T extends Trait ? ImplClass : never ) - export interface OwnImplClassFn extends Fn { - return: Trait.OwnImplClass - } - export type OwnImplInstance = ( - InstanceType> + export type ImplInstance = ( + InstanceType> ) - export interface OwnImplInstanceFn extends Fn { - return: Trait.OwnImplInstance - } - export type OwnImplStaticMembers = ( - StaticMembers> + export type ImplStaticMembers = ( + StaticMembers> ) export type Supertraits = ( - TraitExpression.Traits> + TraitExpression.Traits> ) - export interface SupertraitsFn extends Fn { - return: Trait.Supertraits - } } -export namespace Traits { +export namespace TraitTuple { export type MapAbstract = { [K in keyof T]: K extends keyof [] ? T[K] - : Trait.OwnAbstract + : Trait.Abstract } export type MapStaticAbstract = { [K in keyof T]: K extends keyof [] ? T[K] - : Trait.OwnStaticAbstract + : Trait.StaticAbstract } export type MapImplClass = { [K in keyof T]: K extends keyof [] ? T[K] - : Trait.OwnImplClass + : Trait.ImplClass } export type MapImplInstance = { [K in keyof T]: K extends keyof [] ? T[K] - : Trait.OwnImplInstance + : Trait.ImplInstance } export type MapImplStaticMembers = { [K in keyof T]: K extends keyof [] ? T[K] - : Trait.OwnImplStaticMembers + : Trait.ImplStaticMembers } } @@ -123,8 +104,8 @@ export type TraitConcreteClass> = ( export type TraitInstance> = ( Simplify< ExtendPlain<[ - Trait.OwnAbstract, - Trait.OwnImplInstance, + Trait.Abstract, + Trait.ImplInstance, ]> > ) @@ -132,8 +113,8 @@ export type TraitInstance> = ( export type TraitStaticMembers> = ( Simplify< ExtendPlain<[ - Trait.OwnStaticAbstract, - StaticMembers>, + Trait.StaticAbstract, + Trait.ImplStaticMembers, ]> > ) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 1a1c4c9..36101fa 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,16 +1,16 @@ import { AbstractClass, Class, Simplify } from "type-fest" -import { Trait, TraitInstance, TraitStaticMembers, Traits } from "./Trait" +import { Trait, TraitInstance, TraitStaticMembers, TraitTuple } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { ExtendPlain, StaticMembers } from "./util" export class TraitExpression< - Superclass extends AbstractClass, - const T extends Trait[], + Superclass extends AbstractClass, + const Traits extends Trait[], > { constructor( readonly superclass: Superclass, - readonly traits: T, + readonly traits: Traits, ) {} get extends(): ( @@ -18,7 +18,7 @@ export class TraitExpression< Simplify< ExtendPlain<[ InstanceType, - ...Traits.MapImplInstance, + ...TraitTuple.MapImplInstance, ]> >, @@ -28,7 +28,7 @@ export class TraitExpression< Simplify< ExtendPlain<[ StaticMembers, - ...Traits.MapImplStaticMembers, + ...TraitTuple.MapImplStaticMembers, ]> > ) { @@ -49,19 +49,19 @@ export class TraitExpression< This, Simplify< - ExtendPlain> + ExtendPlain> >, Simplify< - ExtendPlain> + ExtendPlain> >, AbstractClass< Simplify< - ExtendPlain> + ExtendPlain> > > & Simplify< - ExtendPlain> + ExtendPlain> > >( this, @@ -97,7 +97,7 @@ export type Implements< > = ( Simplify< ExtendPlain< - Traits.MapAbstract< + TraitTuple.MapAbstract< TraitExpression.Traits > > @@ -109,7 +109,7 @@ export type ImplementsStatic< > = ( Simplify< ExtendPlain< - Traits.MapStaticAbstract< + TraitTuple.MapStaticAbstract< TraitExpression.Traits > > -- 2.49.1 From 49f0f7b9876ee568198bc28d8d22dd2c7d5c4919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 17:31:22 +0100 Subject: [PATCH 51/68] Fix --- src/TraitBuilder.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 6d61efc..305e0ef 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -20,6 +20,7 @@ type ImplSuper = ( ]> > > & + Simplify< ExtendPlain<[ StaticAbstract, @@ -89,6 +90,7 @@ export class TraitBuilder< > > > & + Simplify< Omit< StaticMembers, @@ -111,7 +113,7 @@ export class TraitBuilder< export const trait = new TraitBuilder( new TraitExpression(TraitExpression.NullSuperclass, []), - {}, - {}, - Super => class extends Super {}, + {} as object, + {} as object, + Super => class extends Super {} as AbstractClass, ) -- 2.49.1 From 8de5750d2e3bb4113d2895e702d66a1828f5838c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 17:50:34 +0100 Subject: [PATCH 52/68] ExtendPlain -> Extend --- src/Trait.ts | 6 +++--- src/TraitBuilder.ts | 6 +++--- src/TraitExpression.ts | 22 +++++++++++----------- src/lib.ts | 6 +++--- src/util/extend.ts | 40 ++++++++++++++++++---------------------- 5 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 4bff053..c98c2c6 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,6 +1,6 @@ import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { ExtendPlain, StaticMembers } from "./util" +import { Extend, StaticMembers } from "./util" export class Trait< @@ -103,7 +103,7 @@ export type TraitConcreteClass> = ( export type TraitInstance> = ( Simplify< - ExtendPlain<[ + Extend<[ Trait.Abstract, Trait.ImplInstance, ]> @@ -112,7 +112,7 @@ export type TraitInstance> = ( export type TraitStaticMembers> = ( Simplify< - ExtendPlain<[ + Extend<[ Trait.StaticAbstract, Trait.ImplStaticMembers, ]> diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 305e0ef..856d63c 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -1,7 +1,7 @@ import { AbstractClass, Simplify } from "type-fest" import { Trait } from "./Trait" import { TraitExpression } from "./TraitExpression" -import { ExtendPlain, StaticMembers } from "./util" +import { Extend, StaticMembers } from "./util" type ImplSuper = ( @@ -14,7 +14,7 @@ type ImplSuper = ( ? ( AbstractClass< Simplify< - ExtendPlain<[ + Extend<[ Abstract, InstanceType, ]> @@ -22,7 +22,7 @@ type ImplSuper = ( > & Simplify< - ExtendPlain<[ + Extend<[ StaticAbstract, StaticMembers, ]> diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 36101fa..733fdc9 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,7 +1,7 @@ import { AbstractClass, Class, Simplify } from "type-fest" import { Trait, TraitInstance, TraitStaticMembers, TraitTuple } from "./Trait" import { TraitBuilder } from "./TraitBuilder" -import { ExtendPlain, StaticMembers } from "./util" +import { Extend, StaticMembers } from "./util" export class TraitExpression< @@ -16,7 +16,7 @@ export class TraitExpression< get extends(): ( AbstractClass< Simplify< - ExtendPlain<[ + Extend<[ InstanceType, ...TraitTuple.MapImplInstance, ]> @@ -26,7 +26,7 @@ export class TraitExpression< > & Simplify< - ExtendPlain<[ + Extend<[ StaticMembers, ...TraitTuple.MapImplStaticMembers, ]> @@ -49,19 +49,19 @@ export class TraitExpression< This, Simplify< - ExtendPlain> + Extend> >, Simplify< - ExtendPlain> + Extend> >, AbstractClass< Simplify< - ExtendPlain> + Extend> > > & Simplify< - ExtendPlain> + Extend> > >( this, @@ -96,7 +96,7 @@ export type Implements< Exp extends TraitExpression[]> > = ( Simplify< - ExtendPlain< + Extend< TraitTuple.MapAbstract< TraitExpression.Traits > @@ -108,7 +108,7 @@ export type ImplementsStatic< Exp extends TraitExpression[]> > = ( Simplify< - ExtendPlain< + Extend< TraitTuple.MapStaticAbstract< TraitExpression.Traits > @@ -141,7 +141,7 @@ export type TraitExpressionInstance< Exp extends TraitExpression[]> > = ( Simplify< - ExtendPlain<[ + Extend<[ InstanceType>, ...MapTraitsInstance>, ]> @@ -159,7 +159,7 @@ export type TraitExpressionStaticMembers< Exp extends TraitExpression[]> > = ( Simplify< - ExtendPlain<[ + Extend<[ StaticMembers>, ...MapTraitsStaticMembers>, ]> diff --git a/src/lib.ts b/src/lib.ts index f268d87..9426d7e 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -1,4 +1,4 @@ -export { type Trait } from "./Trait" -export { trait } from "./TraitBuilder" -export { Implements, ImplementsStatic, type TraitExpression } from "./TraitExpression" +export { Trait, TraitClass, TraitConcreteClass, TraitInstance, TraitStaticMembers, TraitTuple } from "./Trait" +export { TraitBuilder, trait } from "./TraitBuilder" +export { Implements, ImplementsStatic, TraitExpression, TraitExpressionClass, TraitExpressionConcreteClass, TraitExpressionInstance, TraitExpressionStaticMembers } from "./TraitExpression" export { expression } from "./TraitExpressionBuilder" diff --git a/src/util/extend.ts b/src/util/extend.ts index 2592f09..3269bab 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -1,25 +1,22 @@ -import { Call, ComposeLeft, Fn, Match, Tuples } from "hotscript" import { CommonKeys } from "." -type ExtendReducer = ( - Pick> extends Pick> - ? Omit> & Self - : never -) -interface ExtendReducerFn extends Fn { - return: ExtendReducer -} - -export type ExtendFn = Tuples.Reduce -export type Extend = Call +// type ExtendReducer = ( +// Pick> extends Pick> +// ? Omit> & Self +// : never +// ) +// interface ExtendReducerFn extends Fn { +// return: ExtendReducer +// } +// export type ExtendFn = Tuples.Reduce -export type ExtendPlain = ( +export type Extend = ( T extends [infer Super, infer Self, ...infer Rest] ? Rest extends object[] ? Pick> extends Pick> - ? ExtendPlain<[ + ? Extend<[ Omit> & Self, ...Rest, ]> @@ -33,11 +30,10 @@ export type ExtendPlain = ( ) -export type ExtendableFn = ComposeLeft<[ - ExtendFn, - Match<[ - Match.With, - Match.With, - ]> -]> -export type Extendable = Call +// export type ExtendableFn = ComposeLeft<[ +// ExtendFn, +// Match<[ +// Match.With, +// Match.With, +// ]> +// ]> -- 2.49.1 From 394d267d7495387d15e5d5a7a26b96bf29f372f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 17:53:23 +0100 Subject: [PATCH 53/68] Fix --- src/util/extend.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/util/extend.ts b/src/util/extend.ts index 3269bab..b8f2e95 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -11,6 +11,14 @@ import { CommonKeys } from "." // } // export type ExtendFn = Tuples.Reduce +// export type ExtendableFn = ComposeLeft<[ +// ExtendFn, +// Match<[ +// Match.With, +// Match.With, +// ]> +// ]> + export type Extend = ( T extends [infer Super, infer Self, ...infer Rest] @@ -28,12 +36,3 @@ export type Extend = ( : never : {} ) - - -// export type ExtendableFn = ComposeLeft<[ -// ExtendFn, -// Match<[ -// Match.With, -// Match.With, -// ]> -// ]> -- 2.49.1 From b9dc68d97bb1d3f9c7e6a32d71690bd4e4e2ea12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 18:23:09 +0100 Subject: [PATCH 54/68] Extendable --- src/tests.ts | 7 +++++++ src/util/extend.ts | 29 ++++++++++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/tests.ts b/src/tests.ts index 631b011..09fa326 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -2,6 +2,7 @@ import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic, TraitExpressionClass } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" +import { Extendable } from "./util" const PrintsHelloOnNew = trait @@ -81,3 +82,9 @@ class User extends exp.extends implements Implements { } console.log(new User()) + + +type T = Extendable<[ + { prout: string }, + { prout: "gneugneu" }, +]> diff --git a/src/util/extend.ts b/src/util/extend.ts index b8f2e95..d2a3824 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -21,18 +21,25 @@ import { CommonKeys } from "." export type Extend = ( - T extends [infer Super, infer Self, ...infer Rest] - ? Rest extends object[] - ? Pick> extends Pick> - ? Extend<[ - Omit> & Self, - ...Rest, - ]> - : never + T extends [infer Super, infer Self, ...infer Rest extends object[]] + ? Pick> extends Pick> + ? Extend<[ + Omit> & Self, + ...Rest, + ]> : never : T extends [infer Self] - ? Self extends object - ? Self - : never + ? Self : {} ) + +export type Extendable = ( + T extends [infer Super, infer Self, ...infer Rest extends object[]] + ? Pick> extends Pick> + ? Extendable<[ + Omit> & Self, + ...Rest, + ]> + : false + : true +) -- 2.49.1 From 9f36ce85bed4d7a33a947725584e23fad776951e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 19:22:07 +0100 Subject: [PATCH 55/68] Extend work --- src/util/extend.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/util/extend.ts b/src/util/extend.ts index d2a3824..e4a1460 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -21,7 +21,11 @@ import { CommonKeys } from "." export type Extend = ( - T extends [infer Super, infer Self, ...infer Rest extends object[]] + T extends [ + infer Super, + infer Self, + ...infer Rest extends object[] + ] ? Pick> extends Pick> ? Extend<[ Omit> & Self, @@ -34,12 +38,22 @@ export type Extend = ( ) export type Extendable = ( - T extends [infer Super, infer Self, ...infer Rest extends object[]] + T extends [ + infer Super extends object, + infer Self extends object, + ...infer Rest extends object[], + ] ? Pick> extends Pick> ? Extendable<[ - Omit> & Self, + Super & Self, ...Rest, ]> : false : true ) + +export type NonExtendableKeys = ( + Extendable extends false + ? {} + : never +) -- 2.49.1 From eee35e7d595b4117ecf7f7775bfa90fb1962250a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 21:19:25 +0100 Subject: [PATCH 56/68] NonExtendableKeys --- src/tests.ts | 4 ++-- src/util/extend.ts | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/tests.ts b/src/tests.ts index 09fa326..51641af 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -2,7 +2,7 @@ import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic, TraitExpressionClass } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" -import { Extendable } from "./util" +import { Extendable, NonExtendableKeys } from "./util" const PrintsHelloOnNew = trait @@ -84,7 +84,7 @@ class User extends exp.extends implements Implements { console.log(new User()) -type T = Extendable<[ +type T = NonExtendableKeys<[ { prout: string }, { prout: "gneugneu" }, ]> diff --git a/src/util/extend.ts b/src/util/extend.ts index e4a1460..6f1c498 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -24,7 +24,7 @@ export type Extend = ( T extends [ infer Super, infer Self, - ...infer Rest extends object[] + ...infer Rest extends object[], ] ? Pick> extends Pick> ? Extend<[ @@ -39,13 +39,13 @@ export type Extend = ( export type Extendable = ( T extends [ - infer Super extends object, - infer Self extends object, + infer Super, + infer Self, ...infer Rest extends object[], ] ? Pick> extends Pick> ? Extendable<[ - Super & Self, + Omit> & Self, ...Rest, ]> : false @@ -53,7 +53,19 @@ export type Extendable = ( ) export type NonExtendableKeys = ( - Extendable extends false - ? {} - : never + T extends [ + infer Super extends object, + infer Self extends object, + ...infer Rest extends object[], + ] + ? { + [K in keyof Super & keyof Self]: Self[K] extends Super[K] + ? never + : K + }[keyof Super & keyof Self] + | NonExtendableKeys<[ + Super & Self, + ...Rest, + ]> + : void ) -- 2.49.1 From df7e7f3401d345af1615151a0c074d90185ba0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 22:08:24 +0100 Subject: [PATCH 57/68] Fixed TraitExpressionBuilder --- src/Trait.ts | 48 +++++++++++++++++++++----------- src/TraitExpression.ts | 20 ++------------ src/TraitExpressionBuilder.ts | 52 +++++++++++++---------------------- src/tests.ts | 3 +- src/util/extend.ts | 7 ++--- 5 files changed, 59 insertions(+), 71 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index c98c2c6..2ad5dff 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,6 +1,6 @@ import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { Extend, StaticMembers } from "./util" +import { Extend, StaticMembers as StaticMembersUtil } from "./util" export class Trait< @@ -27,6 +27,10 @@ export namespace Trait { : never ) + export type Supertraits = ( + TraitExpression.Traits> + ) + export type Abstract = ( T extends Trait ? Abstract @@ -50,11 +54,21 @@ export namespace Trait { ) export type ImplStaticMembers = ( - StaticMembers> + StaticMembersUtil> ) - export type Supertraits = ( - TraitExpression.Traits> + export type Instance = ( + Extend<[ + Trait.Abstract, + Trait.ImplInstance, + ]> + ) + + export type StaticMembers = ( + Extend<[ + Trait.StaticAbstract, + Trait.ImplStaticMembers, + ]> ) } @@ -88,6 +102,18 @@ export namespace TraitTuple { ? T[K] : Trait.ImplStaticMembers } + + export type MapInstance = { + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.Instance + } + + export type MapStaticMembers = { + [K in keyof T]: K extends keyof [] + ? T[K] + : Trait.StaticMembers + } } @@ -102,19 +128,9 @@ export type TraitConcreteClass> = ( ) export type TraitInstance> = ( - Simplify< - Extend<[ - Trait.Abstract, - Trait.ImplInstance, - ]> - > + Simplify> ) export type TraitStaticMembers> = ( - Simplify< - Extend<[ - Trait.StaticAbstract, - Trait.ImplStaticMembers, - ]> - > + Simplify> ) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 733fdc9..179839a 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -1,5 +1,5 @@ import { AbstractClass, Class, Simplify } from "type-fest" -import { Trait, TraitInstance, TraitStaticMembers, TraitTuple } from "./Trait" +import { Trait, TraitTuple } from "./Trait" import { TraitBuilder } from "./TraitBuilder" import { Extend, StaticMembers } from "./util" @@ -143,17 +143,10 @@ export type TraitExpressionInstance< Simplify< Extend<[ InstanceType>, - ...MapTraitsInstance>, + ...TraitTuple.MapInstance>, ]> > ) -type MapTraitsInstance = { - [K in keyof T]: K extends keyof [] - ? T[K] - : T[K] extends Trait - ? TraitInstance - : never -} export type TraitExpressionStaticMembers< Exp extends TraitExpression[]> @@ -161,14 +154,7 @@ export type TraitExpressionStaticMembers< Simplify< Extend<[ StaticMembers>, - ...MapTraitsStaticMembers>, + ...TraitTuple.MapStaticMembers>, ]> > ) -type MapTraitsStaticMembers = { - [K in keyof T]: K extends keyof [] - ? T[K] - : T[K] extends Trait - ? TraitStaticMembers - : never -} diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index b6b35a6..11bbe5d 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -1,9 +1,9 @@ -import { Call, Fn, Pipe, Tuples } from "hotscript" +import { Call, Fn, Tuples } from "hotscript" import { uniq } from "lodash-es" import { AbstractClass } from "type-fest" -import { Trait } from "./Trait" +import { Trait, TraitTuple } from "./Trait" import { TraitExpression } from "./TraitExpression" -import { ExtendableFn, StaticMembersFn } from "./util" +import { Extendable, StaticMembers } from "./util" type SpreadSupertraits[]> = ( @@ -17,49 +17,35 @@ interface PrependTraitSupertraitsFn extends Fn { } -type AbstractMembersExtendable< - Superclass extends AbstractClass<{}>, +type InstanceExtendable< + Superclass extends AbstractClass, Traits extends Trait[], > = ( - Pipe, - Tuples.Prepend>, + Extendable<[ + InstanceType, + ...TraitTuple.MapInstance, ]> ) -type ImplInstanceExtendable< - Superclass extends AbstractClass<{}>, +type StaticMembersExtendable< + Superclass extends AbstractClass, Traits extends Trait[], > = ( - Pipe, - Tuples.Prepend>, - ]> -) - -type ImplStaticMembersExtendable< - Superclass extends AbstractClass<{}>, - Traits extends Trait[], -> = ( - Pipe, - Tuples.Prepend, - Tuples.Map, - ExtendableFn, + Extendable<[ + StaticMembers, + ...TraitTuple.MapStaticMembers, ]> ) type BuildTraitExpression< - Superclass extends AbstractClass<{}>, + Superclass extends AbstractClass, Traits extends Trait[], > = ( - AbstractMembersExtendable extends false - ? "Type conflict between the traits abstract members and/or the superclass instance." - : ImplInstanceExtendable extends false - ? "Type conflict between the traits implementation instances and/or the superclass instance." - : ImplStaticMembersExtendable extends false - ? "Type conflict between the traits implementation static members and/or the superclass static members." - : TraitExpression + InstanceExtendable extends false + ? "Type conflict on the instance side." + : StaticMembersExtendable extends false + ? "Type conflict on the static side." + : TraitExpression ) diff --git a/src/tests.ts b/src/tests.ts index 51641af..b7ada34 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,3 +1,4 @@ +import { Simplify } from "type-fest" import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic, TraitExpressionClass } from "./TraitExpression" @@ -85,6 +86,6 @@ console.log(new User()) type T = NonExtendableKeys<[ - { prout: string }, { prout: "gneugneu" }, + { prout: string }, ]> diff --git a/src/util/extend.ts b/src/util/extend.ts index 6f1c498..6383bde 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -58,10 +58,9 @@ export type NonExtendableKeys = ( infer Self extends object, ...infer Rest extends object[], ] - ? { - [K in keyof Super & keyof Self]: Self[K] extends Super[K] - ? never - : K + ? {[K in keyof Super & keyof Self]: Self[K] extends Super[K] + ? never + : K }[keyof Super & keyof Self] | NonExtendableKeys<[ Super & Self, -- 2.49.1 From d9213e0083b72b4363e537a6627af1919b744d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 19 Feb 2024 22:41:20 +0100 Subject: [PATCH 58/68] TraitExpression fix --- src/TraitExpression.ts | 18 ++++++++++-------- src/tests.ts | 20 +++++++++++++++----- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 179839a..ade1782 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -15,11 +15,12 @@ export class TraitExpression< get extends(): ( AbstractClass< + InstanceType & // Keep the instance of the superclass outside of any kind of type manipulation + // as it can accidentely remove abstract properties Simplify< - Extend<[ - InstanceType, - ...TraitTuple.MapImplInstance, - ]> + Extend< + TraitTuple.MapImplInstance + > >, ConstructorParameters @@ -140,11 +141,12 @@ export type TraitExpressionConcreteClass< export type TraitExpressionInstance< Exp extends TraitExpression[]> > = ( + InstanceType> & // Keep the instance of the superclass outside of any kind of type manipulation + // as it can accidentely remove abstract properties Simplify< - Extend<[ - InstanceType>, - ...TraitTuple.MapInstance>, - ]> + Extend< + TraitTuple.MapInstance> + > > ) diff --git a/src/tests.ts b/src/tests.ts index b7ada34..3725da4 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,4 +1,4 @@ -import { Simplify } from "type-fest" +import { AbstractClass, Simplify } from "type-fest" import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic, TraitExpressionClass } from "./TraitExpression" @@ -85,7 +85,17 @@ class User extends exp.extends implements Implements { console.log(new User()) -type T = NonExtendableKeys<[ - { prout: "gneugneu" }, - { prout: string }, -]> +abstract class Test { + abstract prout: string +} + +const MappedTest = Test as AbstractClass + +class ConcreteTest extends MappedTest { + +} + +// type T = NonExtendableKeys<[ +// { prout: "gneugneu" }, +// { prout: string }, +// ]> -- 2.49.1 From 94c4307ad2b919681edc4a80b7ae9c89d1a6d2fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:12:05 +0100 Subject: [PATCH 59/68] Fixed SpreadSupertraits --- src/tests.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/tests.ts b/src/tests.ts index 3725da4..daf516b 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,9 +1,7 @@ -import { AbstractClass, Simplify } from "type-fest" import { TraitClass } from "./Trait" import { trait } from "./TraitBuilder" import { Implements, ImplementsStatic, TraitExpressionClass } from "./TraitExpression" import { expression } from "./TraitExpressionBuilder" -import { Extendable, NonExtendableKeys } from "./util" const PrintsHelloOnNew = trait @@ -85,16 +83,6 @@ class User extends exp.extends implements Implements { console.log(new User()) -abstract class Test { - abstract prout: string -} - -const MappedTest = Test as AbstractClass - -class ConcreteTest extends MappedTest { - -} - // type T = NonExtendableKeys<[ // { prout: "gneugneu" }, // { prout: string }, -- 2.49.1 From 50e360d7ff1ddf1dba3b5856ddf7d3c4a624513e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:12:19 +0100 Subject: [PATCH 60/68] Fixed SpreadSupertraits --- src/TraitExpressionBuilder.ts | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 11bbe5d..797f224 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -1,4 +1,3 @@ -import { Call, Fn, Tuples } from "hotscript" import { uniq } from "lodash-es" import { AbstractClass } from "type-fest" import { Trait, TraitTuple } from "./Trait" @@ -6,15 +5,15 @@ import { TraitExpression } from "./TraitExpression" import { Extendable, StaticMembers } from "./util" -type SpreadSupertraits[]> = ( - Call< - Tuples.FlatMap, - Traits - > +type SpreadSupertraits = ( + T extends [infer Trait, ...infer Rest] + ? [ + ...Trait.Supertraits, + Trait, + ...SpreadSupertraits, + ] + : [] ) -interface PrependTraitSupertraitsFn extends Fn { - return: [...Trait.Supertraits, this["arg0"]] -} type InstanceExtendable< @@ -81,10 +80,7 @@ class TraitExpressionBuilder< >[] >( ...traits: T - ): TraitExpressionBuilder< - Superclass, - [...Traits, ...SpreadSupertraits] - > { + ) { return new TraitExpressionBuilder( this.expressionSuperclass, -- 2.49.1 From 3582dea9b391527c4c96663303a9e1b7f5924fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:17:43 +0100 Subject: [PATCH 61/68] Upgrade dependencies --- bun.lockb | Bin 156769 -> 156435 bytes package.json | 7 +++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bun.lockb b/bun.lockb index 8f53293a5d25767695713af6946a36b736e7a416..0e06437060ce846cb44522095b4c044298c209f4 100755 GIT binary patch delta 28574 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 Man5hH`f5G@57;$-L;wH) diff --git a/package.json b/package.json index 347b249..0f8bae7 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "clean:node": "rm -rf node_modules" }, "dependencies": { - "hotscript": "^1.0.13", "lodash-es": "^4.17.21", "type-fest": "^4.10.2" }, @@ -36,12 +35,12 @@ "@rollup/plugin-node-resolve": "^15.2.3", "@types/lodash-es": "^4.17.12", "bun-types": "latest", - "npm-check-updates": "^16.14.14", + "npm-check-updates": "^16.14.15", "npm-sort": "^0.0.4", - "rollup": "^4.9.6", + "rollup": "^4.12.0", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-ts": "^3.4.5", - "tsx": "^4.7.0", + "tsx": "^4.7.1", "typescript": "^5.3.3" } } -- 2.49.1 From 02ce26bd1172af6779f1db27ad72ac26a04bdee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:18:40 +0100 Subject: [PATCH 62/68] Cleanup --- src/util/misc.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/util/misc.ts b/src/util/misc.ts index 3e19396..175ddfd 100644 --- a/src/util/misc.ts +++ b/src/util/misc.ts @@ -1,5 +1,4 @@ -import { Fn } from "hotscript" -import { AbstractClass, Simplify } from "type-fest" +import { AbstractClass } from "type-fest" /** @@ -9,10 +8,6 @@ import { AbstractClass, Simplify } from "type-fest" */ export type CommonKeys = Extract -export interface SimplifyFn extends Fn { - return: Simplify -} - /** * Represents the static members of a class. * @template Class - A class extending AbstractClass. @@ -20,6 +15,3 @@ export interface SimplifyFn extends Fn { export type StaticMembers> = ( Omit ) -export interface StaticMembersFn extends Fn { - return: StaticMembers -} -- 2.49.1 From f9554539bdda073b935b181a0d126dd54d3d1dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:35:05 +0100 Subject: [PATCH 63/68] buildAnyway --- src/TraitExpressionBuilder.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 797f224..d1fdeec 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -104,6 +104,17 @@ class TraitExpressionBuilder< then(fn: (expression: ReturnType) => V): V { return fn(this.build()) } + + buildAnyway() { + return new TraitExpression( + this.expressionSuperclass, + this.expressionTraits, + ) + } + + thenAnyway(fn: (expression: ReturnType) => V): V { + return fn(this.buildAnyway()) + } } export const expression = new TraitExpressionBuilder(TraitExpression.NullSuperclass, []) -- 2.49.1 From 59b13f23af48cfbceb61396d3d61f01ec4538cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:40:03 +0100 Subject: [PATCH 64/68] Fix --- src/Trait.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 2ad5dff..9d43662 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -1,6 +1,6 @@ import { AbstractClass, Class, Simplify } from "type-fest" import { TraitExpression } from "./TraitExpression" -import { Extend, StaticMembers as StaticMembersUtil } from "./util" +import { Extend, StaticMembers } from "./util" export class Trait< @@ -54,7 +54,7 @@ export namespace Trait { ) export type ImplStaticMembers = ( - StaticMembersUtil> + StaticMembers> ) export type Instance = ( @@ -64,7 +64,7 @@ export namespace Trait { ]> ) - export type StaticMembers = ( + export type Static = ( Extend<[ Trait.StaticAbstract, Trait.ImplStaticMembers, @@ -112,7 +112,7 @@ export namespace TraitTuple { export type MapStaticMembers = { [K in keyof T]: K extends keyof [] ? T[K] - : Trait.StaticMembers + : Trait.Static } } @@ -132,5 +132,5 @@ export type TraitInstance> = ( ) export type TraitStaticMembers> = ( - Simplify> + Simplify> ) -- 2.49.1 From e66b15e749a2cc904ba231bb3f49a9fdaf498ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 00:41:40 +0100 Subject: [PATCH 65/68] Added TODO --- src/util/extend.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/extend.ts b/src/util/extend.ts index 6383bde..1618656 100644 --- a/src/util/extend.ts +++ b/src/util/extend.ts @@ -20,6 +20,7 @@ import { CommonKeys } from "." // ]> +// TODO: use OverrideProperties from type-fest? export type Extend = ( T extends [ infer Super, -- 2.49.1 From b3add9aff9b493e9bf77ae6cfaac5728f16e50a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 01:12:38 +0100 Subject: [PATCH 66/68] Switched implSuper to a symbol --- src/TraitBuilder.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 856d63c..3272b11 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -4,6 +4,8 @@ import { TraitExpression } from "./TraitExpression" import { Extend, StaticMembers } from "./util" +declare const implSuperSymbol: unique symbol + type ImplSuper = ( This extends TraitBuilder< any, @@ -27,7 +29,7 @@ type ImplSuper = ( StaticMembers, ]> > & - { readonly _tag: "@thilawyn/traitify-ts/Super" } // TODO: replace with unique symbol? + { readonly [implSuperSymbol]: true } ) : never ) @@ -94,7 +96,7 @@ export class TraitBuilder< Simplify< Omit< StaticMembers, - keyof StaticAbstract | "_tag" + keyof StaticAbstract | typeof implSuperSymbol > > ), -- 2.49.1 From 9ddc998b3d7c4d3b37bc50e71d1b5f691d708505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 01:28:41 +0100 Subject: [PATCH 67/68] nullSuperclassSymbol --- src/TraitExpression.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index ade1782..2490377 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -74,8 +74,9 @@ export class TraitExpression< } export namespace TraitExpression { + declare const nullSuperclassSymbol: unique symbol export class NullSuperclass { - static readonly _tag = "@thilawyn/traitify-ts/TraitExpression.NullSuperclass" + static readonly [nullSuperclassSymbol]: true constructor(...args: any[]) {} } -- 2.49.1 From 1a23309cc379ec0411c0dcfe2fa23d61f6a143f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 20 Feb 2024 01:37:13 +0100 Subject: [PATCH 68/68] Added TODO --- src/TraitBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index 3272b11..a59b333 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -74,7 +74,7 @@ export class TraitBuilder< } implement< - ImplClassWithAbstract extends ImplSuper + ImplClassWithAbstract extends ImplSuper // TODO: find a way to set the constraint to concrete classes while keeping the Super arg as an abstract class >( apply: (Super: ImplSuper) => ImplClassWithAbstract ) { -- 2.49.1