diff --git a/bun.lockb b/bun.lockb index e19e546..ebdb9cc 100755 Binary files a/bun.lockb and b/bun.lockb differ 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