diff --git a/src/index.ts b/src/index.ts index c1ed0f4..e58715f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,7 +21,7 @@ export type 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. @@ -154,6 +154,30 @@ export function extendsAndExpresses< extend: C, ...traits: Traits ) { + // Combine all static members of the traits + type AllStaticMembers = UnionToIntersection> + + // Combine all instance members of the traits + type AllInstanceMembers = UnionToIntersection> + + // 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 + + // Exclude common keys from the instance members of the last trait + type InstanceMembersWithoutCommon = Omit + + // Combine the instance members of the base class and the last trait + type CombinedInstanceMembers = InstanceType & InstanceMembersWithoutCommon + + // Combine the static members of the base class and the last trait + type CombinedStaticMembers = StaticMembers & StaticMembersWithoutCommon + + // Combine the instance and static members + type CombinedMembers = CombinedInstanceMembers & CombinedStaticMembers + return traits.reduce( (previous, trait) => trait(previous), extend as Opaque, diff --git a/src/tests.ts b/src/tests.ts index 6bd14c4..7bfdb96 100644 --- a/src/tests.ts +++ b/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 = () => @@ -68,3 +69,58 @@ class User extends UserProto { const user1 = new User(1n) console.log(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 = { + [Key in keyof C as Key extends "prototype" ? never : Key]: C[Key] +} + +type CommonKeys = Extract + +type Extend2 = ( + Pick> extends Pick> + ? Omit> & Self + : never +) + +type ExtendN = ( + Classes extends [infer Parent, infer Self, ...infer Rest] + ? Extend2 & ExtendN + : Classes extends [infer Self, ...infer Others] + ? Self + : "Empty array" +) + +// type ExtendClass< +// Self extends AbstractClass, +// Parent extends AbstractClass, +// > = ( + +// ) + +type Test = Simplify> +type MixedStaticTestTraits = ExtendN<[ + StaticMembers, + StaticMembers, +]> + +type MixedTestTraitsProto = Class< + Extend2, + any[] +> & Extend2, StaticMembers>