From 4cb9ebd589c884a6c556db638d0f80b87d50a3dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 21 Feb 2024 04:44:24 +0100 Subject: [PATCH] 0.1.7 (#7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julien Valverdé Reviewed-on: https://git.jvalver.de/Thilawyn/traitify-ts/pulls/7 --- package.json | 2 +- src/TraitBuilder.ts | 3 ++ src/TraitExpressionBuilder.ts | 95 ++++++++++++++++++++++++----------- src/tests.ts | 6 --- 4 files changed, 70 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 115a0c5..df29d94 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thilawyn/traitify-ts", - "version": "0.1.6", + "version": "0.1.7", "type": "module", "publishConfig": { "registry": "https://git.jvalver.de/api/packages/thilawyn/npm/" diff --git a/src/TraitBuilder.ts b/src/TraitBuilder.ts index a59b333..bcc45ee 100644 --- a/src/TraitBuilder.ts +++ b/src/TraitBuilder.ts @@ -51,6 +51,7 @@ export class TraitBuilder< private readonly traitApply: (Super: AbstractClass) => ImplClass, ) {} + // TODO: consider "implements" as a name? abstract( _: (Super: AbstractClass) => AbstractClass ) { @@ -62,6 +63,7 @@ export class TraitBuilder< ) } + // TODO: consider "staticImplements" as a name? staticAbstract( _: (Super: AbstractClass) => AbstractClass ) { @@ -73,6 +75,7 @@ export class TraitBuilder< ) } + // TODO: consider "impl" as a name? implement< ImplClassWithAbstract extends ImplSuper // TODO: find a way to set the constraint to concrete classes while keeping the Super arg as an abstract class >( diff --git a/src/TraitExpressionBuilder.ts b/src/TraitExpressionBuilder.ts index 4e222ee..0fd65d6 100644 --- a/src/TraitExpressionBuilder.ts +++ b/src/TraitExpressionBuilder.ts @@ -1,50 +1,61 @@ import { uniq } from "lodash-es" -import { AbstractClass } from "type-fest" +import { AbstractClass, IsEqual } from "type-fest" import { Trait, TraitTuple } from "./Trait" import { TraitExpression } from "./TraitExpression" import { Extendable, StaticMembers } from "./util" -type SpreadSupertraits = ( - T extends [infer Trait, ...infer Rest] +type SpreadSupertraits = ( + Traits extends [ + infer El extends Trait, + ...infer Rest, + ] ? [ - ...Trait.Supertraits, - Trait, + ...Trait.Supertraits, + El, ...SpreadSupertraits, ] : [] ) - -type InstanceExtendable< - Superclass extends AbstractClass, - Traits extends Trait[], -> = ( - Extendable<[ - InstanceType, - ...TraitTuple.MapInstance, - ]> +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 StaticMembersExtendable< - Superclass extends AbstractClass, - Traits extends Trait[], -> = ( - Extendable<[ - StaticMembers, - ...TraitTuple.MapStaticMembers, - ]> -) type BuildTraitExpression< Superclass extends AbstractClass, Traits extends Trait[], > = ( - InstanceExtendable extends false - ? "Type conflict on the instance side." - : StaticMembersExtendable extends false - ? "Type conflict on the static side." - : TraitExpression + 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 ) @@ -90,7 +101,33 @@ export class TraitExpressionBuilder< ...trait.superExpression.traits, trait, ]), - ]) as [...Traits, ...SpreadSupertraits], + ]) as TraitsUniq<[...Traits, ...SpreadSupertraits]>, + ) + } + + expressesFirst< + const T extends Trait< + TraitExpression< + typeof TraitExpression.NullSuperclass, + Trait[] + >, + any, + any, + any + >[] + >( + ...traits: T + ) { + return new TraitExpressionBuilder( + this.expressionSuperclass, + + uniq([ + ...traits.flatMap(trait => [ + ...trait.superExpression.traits, + trait, + ]), + ...this.expressionTraits, + ]) as TraitsUniq<[...SpreadSupertraits, ...Traits]>, ) } diff --git a/src/tests.ts b/src/tests.ts index daf516b..631b011 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -81,9 +81,3 @@ class User extends exp.extends implements Implements { } console.log(new User()) - - -// type T = NonExtendableKeys<[ -// { prout: "gneugneu" }, -// { prout: string }, -// ]>