0.1.1 #8

Merged
Thilawyn merged 6 commits from next into master 2024-01-07 22:49:30 +01:00
4 changed files with 26 additions and 16 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -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",

View File

@@ -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<C> = {
type StaticMembers<C> = {
[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<any>
> =
(Parent: AbstractConstructor<any>) => C
(Parent: AbstractConstructor<object>) => 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<T> =
export type TraitClass<T> =
T extends Trait<infer C>
? C
: never
/**
* Returns the instance type of a trait.
* @template T - The trait type.
*/
export type TraitInstance<T> =
T extends Trait<infer C>
? InstanceType<C>
: never
/**
* Creates a trait using the provided trait applier function.
@@ -90,7 +99,7 @@ export type UnwrapTraitC<T> =
* trait(Parent => {
* abstract class ImplementsIdentifiable extends extendsAndExpresses(
* Parent,
* [Identifiable<ID>()],
* Identifiable<ID>(),
* ) {
* id: ID = defaultID
*
@@ -123,7 +132,10 @@ export function trait<
* @example
* Extends a superclass and applies traits:
* ```ts
* class User extends extendsAndExpresses(Entity, [Identifiable<bigint>(), Permissible]) {
* class User extends extendsAndExpresses(Entity,
* Identifiable<bigint>(),
* Permissible,
* ) {
* readonly id: bigint
*
* constructor(id: bigint) {
@@ -138,7 +150,7 @@ export function extendsAndExpresses<
Traits extends readonly Trait<any>[],
>(
extend: C,
traits: Traits,
...traits: Traits
) {
return traits.reduce(
(previous, trait) => trait(previous),
@@ -147,10 +159,8 @@ export function extendsAndExpresses<
AbstractClass<
InstanceType<C> &
UnionToIntersection<
InstanceType<
UnwrapTraitC<
Traits[number]
>
TraitInstance<
Traits[number]
>
>,
@@ -160,7 +170,7 @@ export function extendsAndExpresses<
StaticMembers<C> &
StaticMembers<
UnionToIntersection<
UnwrapTraitC<
TraitClass<
Traits[number]
>
>
@@ -191,5 +201,5 @@ export function expresses<
>(
...traits: Traits
) {
return extendsAndExpresses(Object, traits)
return extendsAndExpresses(Object, ...traits)
}

View File

@@ -23,7 +23,7 @@ const ImplementsIdentifiable = <ID>(defaultID: ID) =>
trait(Parent => {
abstract class ImplementsIdentifiable extends extendsAndExpresses(
Parent,
[Identifiable<ID>()],
Identifiable<ID>(),
) {
id: ID = defaultID