Trait opaque fix
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Julien Valverdé
2024-02-06 17:27:00 +01:00
parent d14d8b4837
commit 1f19da761f
5 changed files with 38 additions and 37 deletions

View File

@@ -1,5 +1,5 @@
import { Fn, Pipe, Tuples } from "hotscript" import { Fn, Pipe, Tuples } from "hotscript"
import { AbstractClass, Class, Opaque } from "type-fest" import { AbstractClass, Class, Opaque, UnwrapOpaque } from "type-fest"
import { AbstractTag, TraitExpression, emptyTraitExpression } from "." import { AbstractTag, TraitExpression, emptyTraitExpression } from "."
import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util" import { ExtendFn, SimplifyFn, StaticMembers, StaticMembersFn } from "./util"
@@ -16,14 +16,14 @@ export type AddAbstractToImplClass<
) )
export type RemoveAbstractFromImplClass< export type RemoveAbstractFromImplClass<
ImplClassWithAbstract extends Class<Abstract, []>, ImplClassWithAbstract extends Opaque<Class<Abstract, []>, TraitApplierSuperTag>,
Abstract extends {}, Abstract extends {},
> = ( > = (
Class< Class<
Omit<InstanceType<ImplClassWithAbstract>, keyof Abstract>, Omit<InstanceType<ImplClassWithAbstract>, keyof Abstract>,
ConstructorParameters<ImplClassWithAbstract> ConstructorParameters<ImplClassWithAbstract>
> & > &
StaticMembers<ImplClassWithAbstract> UnwrapOpaque<StaticMembers<ImplClassWithAbstract>>
) )
@@ -138,12 +138,10 @@ export type TraitApplierSuperTag = "@thilawyn/traitify-ts/TraitApplierSuper"
export function trait< export function trait<
Abstract extends {}, Abstract extends {},
ImplClassWithAbstract extends Class<Abstract, []>, ImplClassWithAbstract extends Opaque<Class<Abstract, []>, TraitApplierSuperTag>,
>( >(
abstract: Opaque<Abstract, AbstractTag>, abstract: Opaque<Abstract, AbstractTag>,
apply: (Super: Opaque<AbstractClass<Abstract>, TraitApplierSuperTag>) => ( apply: (Super: Opaque<AbstractClass<Abstract>, TraitApplierSuperTag>) => ImplClassWithAbstract,
Opaque<ImplClassWithAbstract, TraitApplierSuperTag>
),
) { ) {
return new Trait( return new Trait(
emptyTraitExpression, emptyTraitExpression,

View File

@@ -12,9 +12,9 @@ import { ExtendFn, SimplifyFn, StaticMembersFn } from "./util"
export class TraitExpression< export class TraitExpression<
Superclass extends AbstractClass<{}>, Superclass extends AbstractClass<{}>,
OwnTraits extends Trait<any, any, any>[], const OwnTraits extends Trait<any, any, any>[],
AllTraits extends Trait<any, any, any>[], const AllTraits extends Trait<any, any, any>[],
> { > {
constructor( constructor(
readonly superclass: Superclass, readonly superclass: Superclass,
@@ -51,13 +51,13 @@ export class TraitExpression<
} }
subtrait< subtrait<
SubtraitAbstract extends Implements<typeof this>, This extends TraitExpression<typeof TraitExpression.NullSuperclass, any, any>,
SubtraitImplClassWithAbstract extends Class<SubtraitAbstract, []>, SubtraitAbstract extends Implements<This>,
SubtraitImplClassWithAbstract extends Opaque<Class<SubtraitAbstract, []>, TraitApplierSuperTag>,
>( >(
abstract: (expression: typeof this) => Opaque<SubtraitAbstract, AbstractTag>, this: This,
apply: (Super: Opaque<AbstractClass<SubtraitAbstract>, TraitApplierSuperTag>) => ( abstract: (expression: This) => Opaque<SubtraitAbstract, AbstractTag>,
Opaque<SubtraitImplClassWithAbstract, TraitApplierSuperTag> apply: (Super: Opaque<AbstractClass<SubtraitAbstract>, TraitApplierSuperTag>) => SubtraitImplClassWithAbstract,
),
) { ) {
return new Trait( return new Trait(
this, this,
@@ -99,11 +99,7 @@ export namespace TraitExpression {
} }
} }
export const emptyTraitExpression = new TraitExpression( export const emptyTraitExpression = new TraitExpression(TraitExpression.NullSuperclass, [], [])
TraitExpression.NullSuperclass,
[] as const,
[] as const,
)
export type Implements<Exp extends TraitExpression<any, any, any>> = ( export type Implements<Exp extends TraitExpression<any, any, any>> = (

View File

@@ -66,11 +66,11 @@ type BuildTraitExpression<
class TraitExpressionBuilder< class TraitExpressionBuilder<
Super extends AbstractClass<{}>, Superclass extends AbstractClass<{}>,
OwnTraits extends Trait<any, any, any>[], const OwnTraits extends Trait<any, any, any>[],
AllTraits extends Trait<any, any, any>[], const AllTraits extends Trait<any, any, any>[],
> { > {
constructor(private expression: TraitExpression<Super, OwnTraits, AllTraits>) {} constructor(private expression: TraitExpression<Superclass, OwnTraits, AllTraits>) {}
extends< extends<
Super extends AbstractClass<any> Super extends AbstractClass<any>
@@ -87,25 +87,25 @@ class TraitExpressionBuilder<
} }
expresses< expresses<
Traits extends Trait<any, any, any>[] const Traits extends Trait<any, any, any>[]
>( >(
...traits: Traits ...traits: Traits
): TraitExpressionBuilder< ): TraitExpressionBuilder<
Super, Superclass,
[...OwnTraits, ...Traits], [...OwnTraits, ...Traits],
[...AllTraits, ...SpreadSupertraits<Traits>] [...AllTraits, ...SpreadSupertraits<Traits>]
> { > {
return new TraitExpressionBuilder( return new TraitExpressionBuilder(
new TraitExpression( new TraitExpression(
this.expression.superclass, this.expression.superclass,
[...this.expression.ownTraits, ...traits] as const, [...this.expression.ownTraits, ...traits],
[...this.expression.allTraits, ...this.spreadSupertraits(traits)] as const, [...this.expression.allTraits, ...this.spreadSupertraits(traits)],
) )
) as any )
} }
private spreadSupertraits< private spreadSupertraits<
Traits extends Trait< const Traits extends Trait<
TraitExpression<any, any, Trait<any, any, any>[]>, TraitExpression<any, any, Trait<any, any, any>[]>,
any, any,
any any
@@ -120,7 +120,7 @@ class TraitExpressionBuilder<
} }
build() { build() {
return this.expression as BuildTraitExpression<Super, OwnTraits, AllTraits> return this.expression as BuildTraitExpression<Superclass, OwnTraits, AllTraits>
} }
then<V>(fn: (expression: ReturnType<typeof this.build>) => V): V { then<V>(fn: (expression: ReturnType<typeof this.build>) => V): V {

View File

@@ -1,3 +1,8 @@
export { export {
AbstractTag, Implements, TraitApplierSuperTag, abstract, expression, trait, type Trait, type TraitExpression Implements,
abstract,
expression,
trait,
type Trait,
type TraitExpression,
} from "." } from "."

View File

@@ -1,17 +1,18 @@
import { Simplify } from "type-fest"
import { Implements, Trait, abstract, expression, trait } from "." import { Implements, Trait, abstract, expression, trait } from "."
import { Pipe } from "hotscript"
const PrintsHelloOnNew = trait( const PrintsHelloOnNew = trait(
abstract(), abstract(),
Super => class PrintsHelloOnNew extends Super { Super => class PrintsHelloOnNew extends Super {
static readonly isPrintsHelloOnNew = true
constructor(...args: any[]) { constructor(...args: any[]) {
super(...args) super(...args)
console.log("Hello!") console.log("Hello!")
} }
}, },
) )
type PrintsHelloOnNewClass = Trait.Class<typeof PrintsHelloOnNew>
const Identifiable = <ID>() => trait( const Identifiable = <ID>() => trait(
abstract<{ readonly id: ID }>(), abstract<{ readonly id: ID }>(),
@@ -34,6 +35,7 @@ const StatefulSubscription = trait(
Super => class StatefulSubscription extends Super {}, Super => class StatefulSubscription extends Super {},
) )
type StatefulSubscriptionClass = Trait.Class<typeof StatefulSubscription>
const ActiveStatefulSubscription = expression const ActiveStatefulSubscription = expression
.expresses(StatefulSubscription) .expresses(StatefulSubscription)
@@ -51,7 +53,7 @@ const ActiveStatefulSubscription = expression
Super => class ActiveStatefulSubscription extends Super {}, Super => class ActiveStatefulSubscription extends Super {},
) )
type T = Trait.Instance<typeof ActiveStatefulSubscription> // type T = Trait.Instance<typeof ActiveStatefulSubscription>
class TestSuperclass { class TestSuperclass {