From d457fb8aada76d436fb0b94ab8a8931332a94b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 7 Jan 2024 22:49:29 +0100 Subject: [PATCH] 0.1.1 (#8) 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/thilatrait/pulls/8 --- bun.lockb | Bin 155585 -> 155617 bytes package.json | 4 ++-- src/index.ts | 36 +++++++++++++++++++++++------------- src/tests.ts | 2 +- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/bun.lockb b/bun.lockb index e19e546aeb10c545d422b3b8aea27b1801b5060a..ebdb9ccf3f92f0376007c22f3ccf9964879d9ea1 100755 GIT binary patch delta 8139 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 F{%=RmFeU&1 delta 8014 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 diff --git a/package.json b/package.json index ba3e42a..8fb25d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thilawyn/thilatrait", - "version": "0.1.0", + "version": "0.1.1", "type": "module", "publishConfig": { "registry": "https://git.jvalver.de/api/packages/thilawyn/npm/" @@ -35,7 +35,7 @@ "bun-types": "latest", "npm-check-updates": "^16.14.12", "npm-sort": "^0.0.4", - "rollup": "^4.9.2", + "rollup": "^4.9.4", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-ts": "^3.4.5", "tsx": "^4.7.0", diff --git a/src/index.ts b/src/index.ts index 8351eca..0d273bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,7 @@ import { AbstractClass, AbstractConstructor, Opaque, UnionToIntersection } from * Represents the static members of a class. * @template C - The class type. */ -export type StaticMembers = { +type StaticMembers = { [Key in keyof C as Key extends "prototype" ? never : Key]: C[Key] } @@ -28,17 +28,26 @@ export type Trait< export type TraitApplier< C extends AbstractClass > = - (Parent: AbstractConstructor) => C + (Parent: AbstractConstructor) => C /** - * Unwraps the type of the class from a given trait. + * Returns the class type of a trait. * @template T - The trait type. */ -export type UnwrapTraitC = +export type TraitClass = T extends Trait ? C : never +/** + * Returns the instance type of a trait. + * @template T - The trait type. + */ +export type TraitInstance = + T extends Trait + ? InstanceType + : never + /** * Creates a trait using the provided trait applier function. @@ -90,7 +99,7 @@ export type UnwrapTraitC = * trait(Parent => { * abstract class ImplementsIdentifiable extends extendsAndExpresses( * Parent, - * [Identifiable()], + * Identifiable(), * ) { * id: ID = defaultID * @@ -123,7 +132,10 @@ export function trait< * @example * Extends a superclass and applies traits: * ```ts - * class User extends extendsAndExpresses(Entity, [Identifiable(), Permissible]) { + * class User extends extendsAndExpresses(Entity, + * Identifiable(), + * Permissible, + * ) { * readonly id: bigint * * constructor(id: bigint) { @@ -138,7 +150,7 @@ export function extendsAndExpresses< Traits extends readonly Trait[], >( extend: C, - traits: Traits, + ...traits: Traits ) { return traits.reduce( (previous, trait) => trait(previous), @@ -147,10 +159,8 @@ export function extendsAndExpresses< AbstractClass< InstanceType & UnionToIntersection< - InstanceType< - UnwrapTraitC< - Traits[number] - > + TraitInstance< + Traits[number] > >, @@ -160,7 +170,7 @@ export function extendsAndExpresses< StaticMembers & StaticMembers< UnionToIntersection< - UnwrapTraitC< + TraitClass< Traits[number] > > @@ -191,5 +201,5 @@ export function expresses< >( ...traits: Traits ) { - return extendsAndExpresses(Object, traits) + return extendsAndExpresses(Object, ...traits) } diff --git a/src/tests.ts b/src/tests.ts index bb49d1f..6bd14c4 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -23,7 +23,7 @@ const ImplementsIdentifiable = (defaultID: ID) => trait(Parent => { abstract class ImplementsIdentifiable extends extendsAndExpresses( Parent, - [Identifiable()], + Identifiable(), ) { id: ID = defaultID