0.1.2 #9
26
src/index.ts
26
src/index.ts
@@ -21,7 +21,7 @@ export type Trait<
|
|||||||
"@thilawyn/thilatrait/Trait"
|
"@thilawyn/thilatrait/Trait"
|
||||||
>
|
>
|
||||||
|
|
||||||
export type TraitApplierTag = "@thilawyn/thilatrait/Trait"
|
export type TraitApplierTag = "@thilawyn/thilatrait/Parent"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the function signature for applying a trait to a parent class.
|
* Represents the function signature for applying a trait to a parent class.
|
||||||
@@ -154,6 +154,30 @@ export function extendsAndExpresses<
|
|||||||
extend: C,
|
extend: C,
|
||||||
...traits: Traits
|
...traits: Traits
|
||||||
) {
|
) {
|
||||||
|
// Combine all static members of the traits
|
||||||
|
type AllStaticMembers = UnionToIntersection<TraitClass<Traits[number]>>
|
||||||
|
|
||||||
|
// Combine all instance members of the traits
|
||||||
|
type AllInstanceMembers = UnionToIntersection<TraitInstance<Traits[number]>>
|
||||||
|
|
||||||
|
// Extract common keys from all traits
|
||||||
|
type CommonKeys = keyof AllStaticMembers & keyof AllInstanceMembers
|
||||||
|
|
||||||
|
// Exclude common keys from the static members of the last trait
|
||||||
|
type StaticMembersWithoutCommon = Omit<AllStaticMembers, CommonKeys>
|
||||||
|
|
||||||
|
// Exclude common keys from the instance members of the last trait
|
||||||
|
type InstanceMembersWithoutCommon = Omit<AllInstanceMembers, CommonKeys>
|
||||||
|
|
||||||
|
// Combine the instance members of the base class and the last trait
|
||||||
|
type CombinedInstanceMembers = InstanceType<C> & InstanceMembersWithoutCommon
|
||||||
|
|
||||||
|
// Combine the static members of the base class and the last trait
|
||||||
|
type CombinedStaticMembers = StaticMembers<C> & StaticMembersWithoutCommon
|
||||||
|
|
||||||
|
// Combine the instance and static members
|
||||||
|
type CombinedMembers = CombinedInstanceMembers & CombinedStaticMembers
|
||||||
|
|
||||||
return traits.reduce(
|
return traits.reduce(
|
||||||
(previous, trait) => trait(previous),
|
(previous, trait) => trait(previous),
|
||||||
extend as Opaque<C, TraitApplierTag>,
|
extend as Opaque<C, TraitApplierTag>,
|
||||||
|
|||||||
58
src/tests.ts
58
src/tests.ts
@@ -1,4 +1,5 @@
|
|||||||
import { expresses, extendsAndExpresses, trait } from "."
|
import { AbstractClass, Class, Simplify } from "type-fest"
|
||||||
|
import { TraitInstance, expresses, extendsAndExpresses, trait } from "."
|
||||||
|
|
||||||
|
|
||||||
const Identifiable = <ID>() =>
|
const Identifiable = <ID>() =>
|
||||||
@@ -68,3 +69,58 @@ class User extends UserProto {
|
|||||||
const user1 = new User(1n)
|
const user1 = new User(1n)
|
||||||
console.log(user1)
|
console.log(user1)
|
||||||
console.log(user1.equals(user1))
|
console.log(user1.equals(user1))
|
||||||
|
|
||||||
|
|
||||||
|
abstract class TestTrait1 {
|
||||||
|
abstract variable: number
|
||||||
|
abstract member: {
|
||||||
|
issou: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TestTrait2 {
|
||||||
|
abstract lol: BigInt
|
||||||
|
abstract member: {
|
||||||
|
issou: "gneugneu",
|
||||||
|
adolf: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type StaticMembers<C> = {
|
||||||
|
[Key in keyof C as Key extends "prototype" ? never : Key]: C[Key]
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonKeys<A, B> = Extract<keyof A, keyof B>
|
||||||
|
|
||||||
|
type Extend2<Self, Parent> = (
|
||||||
|
Pick<Self, CommonKeys<Self, Parent>> extends Pick<Parent, CommonKeys<Self, Parent>>
|
||||||
|
? Omit<Parent, CommonKeys<Self, Parent>> & Self
|
||||||
|
: never
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExtendN<Classes extends any[]> = (
|
||||||
|
Classes extends [infer Parent, infer Self, ...infer Rest]
|
||||||
|
? Extend2<Self, Parent> & ExtendN<Rest>
|
||||||
|
: Classes extends [infer Self, ...infer Others]
|
||||||
|
? Self
|
||||||
|
: "Empty array"
|
||||||
|
)
|
||||||
|
|
||||||
|
// type ExtendClass<
|
||||||
|
// Self extends AbstractClass<any>,
|
||||||
|
// Parent extends AbstractClass<any>,
|
||||||
|
// > = (
|
||||||
|
|
||||||
|
// )
|
||||||
|
|
||||||
|
type Test = Simplify<StaticMembers<typeof TestTrait2>>
|
||||||
|
type MixedStaticTestTraits = ExtendN<[
|
||||||
|
StaticMembers<typeof TestTrait2>,
|
||||||
|
StaticMembers<typeof TestTrait1>,
|
||||||
|
]>
|
||||||
|
|
||||||
|
type MixedTestTraitsProto = Class<
|
||||||
|
Extend2<TestTrait2, TestTrait1>,
|
||||||
|
any[]
|
||||||
|
> & Extend2<StaticMembers<typeof TestTrait2>, StaticMembers<typeof TestTrait1>>
|
||||||
|
|||||||
Reference in New Issue
Block a user