From 2e3878e08d1a9d60d956b33dbbcf344c6e4a5e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 20:41:16 +0100 Subject: [PATCH 1/7] TraitExpressionBuilder refactoring --- src/TraitExpressionBuilder.ts | 175 ++++++++++++++++++++-------------- src/tests.ts | 1 + 2 files changed, 106 insertions(+), 70 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 4ade9dd..e5d3aaa 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -5,75 +5,60 @@ import { TraitExpression } from "./TraitExpression" import { Extendable, StaticMembers } from "./util" -type SpreadSupertraits = ( - Traits extends [ - infer El extends Trait, - ...infer Rest, - ] - ? [ - ...Trait.Supertraits, - El, - ...SpreadSupertraits, - ] - : [] -) - -type TraitsUniq = ( - Traits extends [ - ...infer Rest, - infer El extends Trait, - ] - ? IsTraitInTupleFromRight extends true - ? TraitsUniq - : [...TraitsUniq, El] - : [] -) -type IsTraitInTupleFromRight = ( - Traits extends [...infer Rest, infer El] - ? IsEqual extends true - ? true - : IsTraitInTupleFromRight - : false -) - - -type BuildTraitExpression< - Superclass extends AbstractClass, - Traits extends Trait[], -> = ( - Extendable> extends false - ? "Type conflict between the traits abstract definitions." - : Extendable> extends false - ? "Type conflict between the traits static abstract definitions." - : Extendable<[ - InstanceType, - ...TraitTuple.MapImplInstance, - ]> extends false - ? "Type conflict between the traits implementation instance and/or the superclass instance." - : Extendable<[ - StaticMembers, - ...TraitTuple.MapImplStaticMembers, - ]> extends false - ? "Type conflict between the traits implementation static members and/or the superclass static members." - : TraitExpression -) - - export class TraitExpressionBuilder< Superclass extends AbstractClass, const Traits extends Trait[], > { + declare ["constructor"]: typeof TraitExpressionBuilder + constructor( readonly expressionSuperclass: Superclass, readonly expressionTraits: Traits, ) {} + + static spreadSupertraits< + const T extends Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + any, + any, + any + >[] + >( + traits: T + ) { + return traits.flatMap(trait => [ + ...trait.superExpression.traits, + trait, + ]) as TraitExpressionBuilder.SpreadSupertraits + } + + static uniqTraits< + const T extends Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + any, + any, + any + >[] + >( + traits: T + ) { + return uniq(traits) as TraitExpressionBuilder.UniqTraits + } + + extends< Super extends AbstractClass >( superclass: Super ) { - return new TraitExpressionBuilder( + return new this.constructor( superclass, this.expressionTraits, ) @@ -92,16 +77,13 @@ export class TraitExpressionBuilder< >( ...traits: T ) { - return new TraitExpressionBuilder( + return new this.constructor( this.expressionSuperclass, - uniq([ + this.constructor.uniqTraits([ ...this.expressionTraits, - ...traits.flatMap(trait => [ - ...trait.superExpression.traits, - trait, - ]), - ]) as TraitsUniq<[...Traits, ...SpreadSupertraits]>, + ...this.constructor.spreadSupertraits(traits), + ]), ) } @@ -118,24 +100,22 @@ export class TraitExpressionBuilder< >( ...traits: T ) { - return new TraitExpressionBuilder( + return new this.constructor( this.expressionSuperclass, - uniq([ - ...traits.flatMap(trait => [ - ...trait.superExpression.traits, - trait, - ]), + this.constructor.uniqTraits([ + ...this.constructor.spreadSupertraits(traits), ...this.expressionTraits, - ]) as TraitsUniq<[...SpreadSupertraits, ...Traits]>, + ]), ) } + build() { return new TraitExpression( this.expressionSuperclass, this.expressionTraits, - ) as BuildTraitExpression + ) as TraitExpressionBuilder.BuildTraitExpression } then(fn: (expression: ReturnType) => V): V { @@ -154,4 +134,59 @@ export class TraitExpressionBuilder< } } +export namespace TraitExpressionBuilder { + export type SpreadSupertraits = ( + Traits extends [ + infer El extends Trait, + ...infer Rest, + ] + ? [ + ...Trait.Supertraits, + El, + ...SpreadSupertraits, + ] + : [] + ) + + export type UniqTraits = ( + Traits extends [ + ...infer Rest, + infer El extends Trait, + ] + ? IsTraitInTupleFromRight extends true + ? UniqTraits + : [...UniqTraits, El] + : [] + ) + type IsTraitInTupleFromRight = ( + Traits extends [...infer Rest, infer El] + ? IsEqual extends true + ? true + : IsTraitInTupleFromRight + : false + ) + + export type BuildTraitExpression< + Superclass extends AbstractClass, + Traits extends Trait[], + > = ( + Extendable> extends false + ? "Type conflict between the traits abstract definitions." + : Extendable> extends false + ? "Type conflict between the traits static abstract definitions." + : Extendable<[ + InstanceType, + ...TraitTuple.MapImplInstance, + ]> extends false + ? "Type conflict between the traits implementation instance and/or the superclass instance." + : Extendable<[ + StaticMembers, + ...TraitTuple.MapImplStaticMembers, + ]> extends false + ? "Type conflict between the traits implementation static members and/or the superclass static members." + : TraitExpression + ) +} + + export const expression = new TraitExpressionBuilder(TraitExpression.NullSuperclass, []) diff --git a/src/tests.ts b/src/tests.ts index 2618486..af9b93f 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -64,6 +64,7 @@ const exp = expression PrintsHelloOnNew, Identifiable(), // Identifiable(), + // StatefulSubscription, ActiveStatefulSubscription, ) .build() -- 2.49.1 From e2d53644870840ef9662a27b3d7634ac8a3a8882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 21:06:44 +0100 Subject: [PATCH 2/7] TraitBuilder refactoring --- src/TraitBuilder.ts | 73 +++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index b6f698a..b0e4f3c 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -6,34 +6,6 @@ import { Extend, StaticMembers } from "./util" declare const implSuperSymbol: unique symbol -type ImplSuper = ( - This extends TraitBuilder< - any, - infer Abstract, - infer StaticAbstract, - infer ImplClass - > - ? ( - AbstractClass< - Simplify< - Extend<[ - Abstract, - InstanceType, - ]> - > - > & - - Simplify< - Extend<[ - StaticAbstract, - StaticMembers, - ]> - > & - { readonly [implSuperSymbol]: true } - ) - : never -) - export class TraitBuilder< SuperExpression extends TraitExpression< @@ -44,6 +16,8 @@ export class TraitBuilder< StaticAbstract extends object, ImplClass extends AbstractClass, > { + declare ["constructor"]: typeof TraitBuilder + constructor( readonly traitSuperExpression: SuperExpression, readonly traitAbstract: Abstract, @@ -51,10 +25,11 @@ export class TraitBuilder< readonly traitApply: (Super: AbstractClass) => ImplClass, ) {} + abstract( _: (Super: AbstractClass) => AbstractClass ) { - return new TraitBuilder( + return new this.constructor( this.traitSuperExpression, {} as Simplify, this.traitStaticAbstract, @@ -65,7 +40,7 @@ export class TraitBuilder< staticAbstract( _: (Super: AbstractClass) => AbstractClass ) { - return new TraitBuilder( + return new this.constructor( this.traitSuperExpression, this.traitAbstract, {} as Simplify, @@ -74,11 +49,11 @@ export class TraitBuilder< } implement< - ImplClassWithAbstract extends ImplSuper // TODO: find a way to set the constraint to concrete classes while keeping the Super arg as an abstract class + ImplClassWithAbstract extends TraitBuilder.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 + apply: (Super: TraitBuilder.ImplSuper) => ImplClassWithAbstract ) { - return new TraitBuilder( + return new this.constructor( this.traitSuperExpression, this.traitAbstract, this.traitStaticAbstract, @@ -103,6 +78,7 @@ export class TraitBuilder< ) } + build() { return new Trait( this.traitSuperExpression, @@ -113,6 +89,37 @@ export class TraitBuilder< } } +export namespace TraitBuilder { + export type ImplSuper = ( + This extends TraitBuilder< + any, + infer Abstract, + infer StaticAbstract, + infer ImplClass + > + ? ( + AbstractClass< + Simplify< + Extend<[ + Abstract, + InstanceType, + ]> + > + > & + + Simplify< + Extend<[ + StaticAbstract, + StaticMembers, + ]> + > & + { readonly [implSuperSymbol]: true } + ) + : never + ) +} + + export const trait = new TraitBuilder( new TraitExpression(TraitExpression.NullSuperclass, []), {} as object, -- 2.49.1 From f8a3c7dedeee2c313490c4f41a5dabf9827e77b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 21:41:49 +0100 Subject: [PATCH 3/7] UniqTraits -> TraitsUniq --- src/TraitExpressionBuilder.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index e5d3aaa..004ba8e 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -36,7 +36,7 @@ export class TraitExpressionBuilder< ]) as TraitExpressionBuilder.SpreadSupertraits } - static uniqTraits< + static traitsUniq< const T extends Trait< TraitExpression< typeof TraitExpression.NullSuperclass, @@ -49,7 +49,7 @@ export class TraitExpressionBuilder< >( traits: T ) { - return uniq(traits) as TraitExpressionBuilder.UniqTraits + return uniq(traits) as TraitExpressionBuilder.TraitsUniq } @@ -80,7 +80,7 @@ export class TraitExpressionBuilder< return new this.constructor( this.expressionSuperclass, - this.constructor.uniqTraits([ + this.constructor.traitsUniq([ ...this.expressionTraits, ...this.constructor.spreadSupertraits(traits), ]), @@ -103,7 +103,7 @@ export class TraitExpressionBuilder< return new this.constructor( this.expressionSuperclass, - this.constructor.uniqTraits([ + this.constructor.traitsUniq([ ...this.constructor.spreadSupertraits(traits), ...this.expressionTraits, ]), @@ -148,14 +148,14 @@ export namespace TraitExpressionBuilder { : [] ) - export type UniqTraits = ( + export type TraitsUniq = ( Traits extends [ ...infer Rest, infer El extends Trait, ] ? IsTraitInTupleFromRight extends true - ? UniqTraits - : [...UniqTraits, El] + ? TraitsUniq + : [...TraitsUniq, El] : [] ) type IsTraitInTupleFromRight = ( -- 2.49.1 From dc410016515f630d970d32aeaa11c0ca6cf43c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 22:28:37 +0100 Subject: [PATCH 4/7] TraitExpressionBuilder refactoring --- src/TraitExpressionBuilder.ts | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 004ba8e..aa9acec 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -76,7 +76,10 @@ export class TraitExpressionBuilder< >[] >( ...traits: T - ) { + ): TraitExpressionBuilder< + Superclass, + TraitExpressionBuilder.ExpressesReturnTypeTraits + > { return new this.constructor( this.expressionSuperclass, @@ -99,7 +102,10 @@ export class TraitExpressionBuilder< >[] >( ...traits: T - ) { + ): TraitExpressionBuilder< + Superclass, + TraitExpressionBuilder.ExpressesFirstReturnTypeTraits + > { return new this.constructor( this.expressionSuperclass, @@ -166,6 +172,26 @@ export namespace TraitExpressionBuilder { : false ) + export type ExpressesReturnTypeTraits< + Traits extends readonly Trait[], + T extends readonly Trait[], + > = ( + TraitExpressionBuilder.TraitsUniq<[ + ...Traits, + ...TraitExpressionBuilder.SpreadSupertraits, + ]> + ) + + export type ExpressesFirstReturnTypeTraits< + Traits extends readonly Trait[], + T extends readonly Trait[], + > = ( + TraitExpressionBuilder.TraitsUniq<[ + ...TraitExpressionBuilder.SpreadSupertraits, + ...Traits, + ]> + ) + export type BuildTraitExpression< Superclass extends AbstractClass, Traits extends Trait[], -- 2.49.1 From bb1ae3b48f5955258aed7f3720147dec87cce9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 22:50:06 +0100 Subject: [PATCH 5/7] Trait refactoring --- src/Trait.ts | 2 +- src/TraitBuilder.ts | 2 +- src/TraitExpression.ts | 14 +++++++------- src/TraitExpressionBuilder.ts | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Trait.ts b/src/Trait.ts index 9d43662..63109a6 100644 --- a/src/Trait.ts +++ b/src/Trait.ts @@ -6,7 +6,7 @@ import { Extend, StaticMembers } from "./util" export class Trait< SuperExpression extends TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[] + readonly Trait[] >, Abstract extends object, StaticAbstract extends object, diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index b0e4f3c..abe27ae 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -10,7 +10,7 @@ declare const implSuperSymbol: unique symbol export class TraitBuilder< SuperExpression extends TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[] + readonly Trait[] >, Abstract extends object, StaticAbstract extends object, diff --git a/src/TraitExpression.ts b/src/TraitExpression.ts index 62b3624..44367d0 100644 --- a/src/TraitExpression.ts +++ b/src/TraitExpression.ts @@ -6,7 +6,7 @@ import { Extend, StaticMembers } from "./util" export class TraitExpression< Superclass extends AbstractClass, - const Traits extends Trait[], + const Traits extends readonly Trait[], > { constructor( readonly superclass: Superclass, @@ -95,7 +95,7 @@ export namespace TraitExpression { export type Implements< - Exp extends TraitExpression[]> + Exp extends TraitExpression[]> > = ( Simplify< Extend< @@ -107,7 +107,7 @@ export type Implements< ) export type StaticImplements< - Exp extends TraitExpression[]> + Exp extends TraitExpression[]> > = ( Simplify< Extend< @@ -120,7 +120,7 @@ export type StaticImplements< export type TraitExpressionClass< - Exp extends TraitExpression[]> + Exp extends TraitExpression[]> > = ( AbstractClass< TraitExpressionInstance, @@ -130,7 +130,7 @@ export type TraitExpressionClass< ) export type TraitExpressionConcreteClass< - Exp extends TraitExpression[]> + Exp extends TraitExpression[]> > = ( Class< TraitExpressionInstance, @@ -140,7 +140,7 @@ export type TraitExpressionConcreteClass< ) export type TraitExpressionInstance< - Exp extends TraitExpression[]> + Exp extends TraitExpression[]> > = ( InstanceType> & // Keep the instance of the superclass outside of any kind of type manipulation // as it can accidentely remove abstract properties @@ -152,7 +152,7 @@ export type TraitExpressionInstance< ) export type TraitExpressionStaticMembers< - Exp extends TraitExpression[]> + Exp extends TraitExpression[]> > = ( Simplify< Extend<[ diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index aa9acec..94e6ff2 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -7,7 +7,7 @@ import { Extendable, StaticMembers } from "./util" export class TraitExpressionBuilder< Superclass extends AbstractClass, - const Traits extends Trait[], + const Traits extends readonly Trait[], > { declare ["constructor"]: typeof TraitExpressionBuilder @@ -21,7 +21,7 @@ export class TraitExpressionBuilder< const T extends Trait< TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[] + readonly Trait[] >, any, any, @@ -40,7 +40,7 @@ export class TraitExpressionBuilder< const T extends Trait< TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[] + readonly Trait[] >, any, any, @@ -68,7 +68,7 @@ export class TraitExpressionBuilder< const T extends Trait< TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[] + readonly Trait[] >, any, any, @@ -94,7 +94,7 @@ export class TraitExpressionBuilder< const T extends Trait< TraitExpression< typeof TraitExpression.NullSuperclass, - Trait[] + readonly Trait[] >, any, any, @@ -194,7 +194,7 @@ export namespace TraitExpressionBuilder { export type BuildTraitExpression< Superclass extends AbstractClass, - Traits extends Trait[], + Traits extends readonly Trait[], > = ( Extendable> extends false ? "Type conflict between the traits abstract definitions." -- 2.49.1 From 0fc49b5290e2c48da253cc1b60000fc7ac47fdff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 22:57:28 +0100 Subject: [PATCH 6/7] Fix --- src/TraitExpressionBuilder.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 94e6ff2..2885fe6 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -18,7 +18,7 @@ export class TraitExpressionBuilder< static spreadSupertraits< - const T extends Trait< + const T extends readonly Trait< TraitExpression< typeof TraitExpression.NullSuperclass, readonly Trait[] @@ -37,7 +37,7 @@ export class TraitExpressionBuilder< } static traitsUniq< - const T extends Trait< + const T extends readonly Trait< TraitExpression< typeof TraitExpression.NullSuperclass, readonly Trait[] @@ -65,7 +65,7 @@ export class TraitExpressionBuilder< } expresses< - const T extends Trait< + const T extends readonly Trait< TraitExpression< typeof TraitExpression.NullSuperclass, readonly Trait[] @@ -91,7 +91,7 @@ export class TraitExpressionBuilder< } expressesFirst< - const T extends Trait< + const T extends readonly Trait< TraitExpression< typeof TraitExpression.NullSuperclass, readonly Trait[] -- 2.49.1 From 538ce1d5fdd5dcabf9d7a1212954d5b4db65aaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 24 Feb 2024 23:39:07 +0100 Subject: [PATCH 7/7] Version bump --- bun.lockb | Bin 156435 -> 156435 bytes package.json | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bun.lockb b/bun.lockb index 0e06437060ce846cb44522095b4c044298c209f4..24092f7c18f09075d6a97fc64b43a705770b1eb5 100755 GIT binary patch delta 151 zcmV;I0BHY{#tD}KS);x>USHXIZ!P8rV|`teWfcLr=_8N7f{b?Wu}%sa zlhi{flRz2>vxpjHe?TO)@{TOx)4i;ip@wmofFv-D!Q}iW;4ViQk7rhf?J*I9h@;2U zM3=ygg}V3Y6?mz7i`E0R6kkU#!=zSetFVJDnzt>Q0Ra#JGq*3Q0U$k>^EUz^w{YhH FqkDlFM4$iw delta 151 zcmV;I0BHY{#tDvxpjHe?V$_KpU;_N|!`zybh>;3-gPskiL(JQYgQ144MKVg*aZmA6kgS zD8KH3w;eE*(_Fr8Fjwcc{Tp>b(C{d6TOWfhnzt>Q0Ra#JGPf_P0U$k>;zt4?w{PbG Fq