Co-authored-by: Julien Valverdé <julien.valverde@mailo.com> Reviewed-on: https://git.jvalver.de/Thilawyn/thilatrait/pulls/8
This commit was merged in pull request #8.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@thilawyn/thilatrait",
|
"name": "@thilawyn/thilatrait",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"registry": "https://git.jvalver.de/api/packages/thilawyn/npm/"
|
"registry": "https://git.jvalver.de/api/packages/thilawyn/npm/"
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
"bun-types": "latest",
|
"bun-types": "latest",
|
||||||
"npm-check-updates": "^16.14.12",
|
"npm-check-updates": "^16.14.12",
|
||||||
"npm-sort": "^0.0.4",
|
"npm-sort": "^0.0.4",
|
||||||
"rollup": "^4.9.2",
|
"rollup": "^4.9.4",
|
||||||
"rollup-plugin-cleanup": "^3.2.1",
|
"rollup-plugin-cleanup": "^3.2.1",
|
||||||
"rollup-plugin-ts": "^3.4.5",
|
"rollup-plugin-ts": "^3.4.5",
|
||||||
"tsx": "^4.7.0",
|
"tsx": "^4.7.0",
|
||||||
|
|||||||
36
src/index.ts
36
src/index.ts
@@ -5,7 +5,7 @@ import { AbstractClass, AbstractConstructor, Opaque, UnionToIntersection } from
|
|||||||
* Represents the static members of a class.
|
* Represents the static members of a class.
|
||||||
* @template C - The class type.
|
* @template C - The class type.
|
||||||
*/
|
*/
|
||||||
export type StaticMembers<C> = {
|
type StaticMembers<C> = {
|
||||||
[Key in keyof C as Key extends "prototype" ? never : Key]: C[Key]
|
[Key in keyof C as Key extends "prototype" ? never : Key]: C[Key]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,17 +28,26 @@ export type Trait<
|
|||||||
export type TraitApplier<
|
export type TraitApplier<
|
||||||
C extends AbstractClass<any>
|
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.
|
* @template T - The trait type.
|
||||||
*/
|
*/
|
||||||
export type UnwrapTraitC<T> =
|
export type TraitClass<T> =
|
||||||
T extends Trait<infer C>
|
T extends Trait<infer C>
|
||||||
? C
|
? C
|
||||||
: never
|
: 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.
|
* Creates a trait using the provided trait applier function.
|
||||||
@@ -90,7 +99,7 @@ export type UnwrapTraitC<T> =
|
|||||||
* trait(Parent => {
|
* trait(Parent => {
|
||||||
* abstract class ImplementsIdentifiable extends extendsAndExpresses(
|
* abstract class ImplementsIdentifiable extends extendsAndExpresses(
|
||||||
* Parent,
|
* Parent,
|
||||||
* [Identifiable<ID>()],
|
* Identifiable<ID>(),
|
||||||
* ) {
|
* ) {
|
||||||
* id: ID = defaultID
|
* id: ID = defaultID
|
||||||
*
|
*
|
||||||
@@ -123,7 +132,10 @@ export function trait<
|
|||||||
* @example
|
* @example
|
||||||
* Extends a superclass and applies traits:
|
* Extends a superclass and applies traits:
|
||||||
* ```ts
|
* ```ts
|
||||||
* class User extends extendsAndExpresses(Entity, [Identifiable<bigint>(), Permissible]) {
|
* class User extends extendsAndExpresses(Entity,
|
||||||
|
* Identifiable<bigint>(),
|
||||||
|
* Permissible,
|
||||||
|
* ) {
|
||||||
* readonly id: bigint
|
* readonly id: bigint
|
||||||
*
|
*
|
||||||
* constructor(id: bigint) {
|
* constructor(id: bigint) {
|
||||||
@@ -138,7 +150,7 @@ export function extendsAndExpresses<
|
|||||||
Traits extends readonly Trait<any>[],
|
Traits extends readonly Trait<any>[],
|
||||||
>(
|
>(
|
||||||
extend: C,
|
extend: C,
|
||||||
traits: Traits,
|
...traits: Traits
|
||||||
) {
|
) {
|
||||||
return traits.reduce(
|
return traits.reduce(
|
||||||
(previous, trait) => trait(previous),
|
(previous, trait) => trait(previous),
|
||||||
@@ -147,10 +159,8 @@ export function extendsAndExpresses<
|
|||||||
AbstractClass<
|
AbstractClass<
|
||||||
InstanceType<C> &
|
InstanceType<C> &
|
||||||
UnionToIntersection<
|
UnionToIntersection<
|
||||||
InstanceType<
|
TraitInstance<
|
||||||
UnwrapTraitC<
|
Traits[number]
|
||||||
Traits[number]
|
|
||||||
>
|
|
||||||
>
|
>
|
||||||
>,
|
>,
|
||||||
|
|
||||||
@@ -160,7 +170,7 @@ export function extendsAndExpresses<
|
|||||||
StaticMembers<C> &
|
StaticMembers<C> &
|
||||||
StaticMembers<
|
StaticMembers<
|
||||||
UnionToIntersection<
|
UnionToIntersection<
|
||||||
UnwrapTraitC<
|
TraitClass<
|
||||||
Traits[number]
|
Traits[number]
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
@@ -191,5 +201,5 @@ export function expresses<
|
|||||||
>(
|
>(
|
||||||
...traits: Traits
|
...traits: Traits
|
||||||
) {
|
) {
|
||||||
return extendsAndExpresses(Object, traits)
|
return extendsAndExpresses(Object, ...traits)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const ImplementsIdentifiable = <ID>(defaultID: ID) =>
|
|||||||
trait(Parent => {
|
trait(Parent => {
|
||||||
abstract class ImplementsIdentifiable extends extendsAndExpresses(
|
abstract class ImplementsIdentifiable extends extendsAndExpresses(
|
||||||
Parent,
|
Parent,
|
||||||
[Identifiable<ID>()],
|
Identifiable<ID>(),
|
||||||
) {
|
) {
|
||||||
id: ID = defaultID
|
id: ID = defaultID
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user