diff --git a/src/index.ts b/src/index.ts index e58715f..ea9c1b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -154,30 +154,6 @@ 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 7bfdb96..ac733c4 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,5 +1,5 @@ -import { AbstractClass, Class, Simplify } from "type-fest" -import { TraitInstance, expresses, extendsAndExpresses, trait } from "." +import { AbstractClass } from "type-fest" +import { expresses, extendsAndExpresses, trait } from "." const Identifiable = () => @@ -71,56 +71,84 @@ console.log(user1) console.log(user1.equals(user1)) -abstract class TestTrait1 { - abstract variable: number - abstract member: { - issou: string - } +abstract class Test1 { + declare static name: string + abstract name: string + + declare createdAt: Date + declare readonly status: ( + { _tag: "awaitingPayment" } | + { _tag: "active", activeSince: Date, expiresAt?: Date } | + { _tag: "expired", expiredSince: Date } + ) } -abstract class TestTrait2 { - abstract lol: BigInt - abstract member: { - issou: "gneugneu", - adolf: string - } +class Test2 { + declare readonly status: { _tag: "active", activeSince: Date, expiresAt?: Date } } - -type StaticMembers = { - [Key in keyof C as Key extends "prototype" ? never : Key]: C[Key] +class Test3 { + declare lol: 10n } + 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] +type Extend = ( + T extends [infer Super, infer Self, ...infer Rest] + ? Pick> extends Pick> + ? Extend<[ + Omit> & Self, + ...Rest, + ]> + : never + : T extends [infer Self] ? Self : "Empty array" ) -// type ExtendClass< -// Self extends AbstractClass, -// Parent extends AbstractClass, -// > = ( +type ClassesInstances = ( + Classes extends [infer Class, ...infer Rest] + ? Class extends AbstractClass + ? [InstanceType, ...ClassesInstances] + : never + : [] +) -// ) +type StaticMembers> = ( + Omit +) -type Test = Simplify> -type MixedStaticTestTraits = ExtendN<[ - StaticMembers, - StaticMembers, +type ClassesStaticMembers = ( + Classes extends [infer Class, ...infer Rest] + ? Class extends AbstractClass + ? [StaticMembers, ...ClassesStaticMembers] + : never + : [] +) + +type ExtendClasses[]> = ( + AbstractClass< + Extend> + > & + Extend> +) + + +type MixedTestProto = ExtendClasses<[ + typeof Test1, + typeof Test2, + typeof Test3, ]> -type MixedTestTraitsProto = Class< - Extend2, - any[] -> & Extend2, StaticMembers> +declare const MixedTestProto: MixedTestProto + +class MixedTest extends MixedTestProto {} + +MixedTest.prototype +new MixedTest().name + +// type MixedTestTraitsProto = Class< +// Extend2, +// any[] +// > & Extend2, StaticMembers>