From c1097ff2f2374e7fb6e7fbd49344dc8d7b0a0deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 3 Feb 2024 02:18:36 +0100 Subject: [PATCH] Trait refactoring --- src/abstract.ts | 8 ++++++-- src/tests.ts | 45 ++++++++++++++++++++++++--------------------- src/trait.ts | 23 +++++++++++++---------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/abstract.ts b/src/abstract.ts index ee9dc5e..bfe4987 100644 --- a/src/abstract.ts +++ b/src/abstract.ts @@ -3,6 +3,10 @@ import { Opaque } from "type-fest" export type AbstractTag = "@thilawyn/traitify-ts/Abstract" -export function abstract() { - return {} as Opaque +export function abstract< + Abstract extends {} = {} +>(): ( + Opaque +) { + return undefined as any } diff --git a/src/tests.ts b/src/tests.ts index cc7f851..ffb6a18 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,41 +1,44 @@ -import { Implements, TraitAbstractMembers, expression, trait } from "." +import { Implements, TraitAbstractMembers, abstract, expression, trait } from "." -const PrintsHelloOnNew = trait()(Super => - class PrintsHelloOnNew extends Super { +const PrintsHelloOnNew = trait( + abstract(), + Super => class PrintsHelloOnNew extends Super { constructor(...args: any[]) { super(...args) console.log("Hello!") } - } + }, ) -const Identifiable = () => ( - trait<{ readonly id: ID }>()(Super => - class Identifiable extends Super { - equals(el: Identifiable) { - return this.id === el.id - } +const Identifiable = () => trait( + abstract<{ readonly id: ID }>(), + Super => class Identifiable extends Super { + equals(el: Identifiable) { + return this.id === el.id } - ) + }, ) -const StatefulSubscription = trait<{ - readonly status: ( - { _tag: "awaitingPayment" } | - { _tag: "active", activeSince: Date, expiresAt?: Date } | - { _tag: "expired", expiredSince: Date } - ) -}>()(Super => - class StatefulSubscription extends Super {} +const StatefulSubscription = trait( + abstract<{ + readonly status: ( + { _tag: "awaitingPayment" } | + { _tag: "active", activeSince: Date, expiresAt?: Date } | + { _tag: "expired", expiredSince: Date } + ) + }>(), + + Super => class StatefulSubscription extends Super {}, ) interface ActiveStatefulSubscriptionAbstractMembers extends TraitAbstractMembers { readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date } } -const ActiveStatefulSubscription = trait()(Super => - class ActiveStatefulSubscription extends Super {} +const ActiveStatefulSubscription = trait( + abstract(), + Super => class ActiveStatefulSubscription extends Super {}, ) diff --git a/src/trait.ts b/src/trait.ts index 6309935..6d5e5fc 100644 --- a/src/trait.ts +++ b/src/trait.ts @@ -1,6 +1,7 @@ import { Fn } from "hotscript" import { AbstractClass, Class, Opaque } from "type-fest" import { StaticMembers } from "./util" +import { AbstractTag } from "." type AddAbstractToImpl< @@ -105,14 +106,16 @@ export type TraitApplier< ) export function trait< - Abstract extends object = {} ->(): ( - >( - apply: TraitApplier - ) => Trait< - Abstract, - RemoveAbstractFromImpl - > -) { - return apply => ({ apply }) as any + Abstract extends {}, + ImplWithAbstract extends Class, +>( + abstract: Opaque, + apply: (Super: Opaque, TraitApplierSuperTag>) => ( + Opaque + ), +): Trait< + Abstract, + RemoveAbstractFromImpl +> { + return { apply } as any }