0.1.2 #9
53
src/tests.ts
53
src/tests.ts
@@ -1,5 +1,6 @@
|
||||
import { AbstractClass } from "type-fest"
|
||||
import { AbstractClass, UnionToIntersection } from "type-fest"
|
||||
import { expresses, extendsAndExpresses, trait } from "."
|
||||
import { ClassesInstances, ClassesInstancesIntersection, ClassesStaticMembers, MergeInheritanceTree, MergeInheritanceTreeWithoutOverriding } from "./util"
|
||||
|
||||
|
||||
const Identifiable = <ID>() =>
|
||||
@@ -92,46 +93,16 @@ class Test3 {
|
||||
}
|
||||
|
||||
|
||||
type CommonKeys<A, B> = Extract<keyof A, keyof B>
|
||||
|
||||
type Extend<T extends readonly any[]> = (
|
||||
T extends [infer Super, infer Self, ...infer Rest]
|
||||
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? Extend<[
|
||||
Omit<Super, CommonKeys<Self, Super>> & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: never
|
||||
: T extends [infer Self]
|
||||
? Self
|
||||
: "Empty array"
|
||||
)
|
||||
|
||||
type ClassesInstances<Classes extends readonly any[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? [InstanceType<Class>, ...ClassesInstances<Rest>]
|
||||
: never
|
||||
: []
|
||||
)
|
||||
|
||||
type StaticMembers<Class extends AbstractClass<any>> = (
|
||||
Omit<Class, "prototype">
|
||||
)
|
||||
|
||||
type ClassesStaticMembers<Classes extends readonly any[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? [StaticMembers<Class>, ...ClassesStaticMembers<Rest>]
|
||||
: never
|
||||
: []
|
||||
)
|
||||
|
||||
type ExtendClasses<Classes extends readonly AbstractClass<any>[]> = (
|
||||
AbstractClass<
|
||||
Extend<ClassesInstances<Classes>>
|
||||
// Extend<ClassesInstances<Classes>>
|
||||
MergeInheritanceTreeWithoutOverriding<
|
||||
ClassesInstances<Classes>
|
||||
>
|
||||
> &
|
||||
Extend<ClassesStaticMembers<Classes>>
|
||||
MergeInheritanceTree<
|
||||
ClassesStaticMembers<Classes>
|
||||
>
|
||||
)
|
||||
|
||||
|
||||
@@ -140,13 +111,13 @@ type MixedTestProto = ExtendClasses<[
|
||||
typeof Test2,
|
||||
typeof Test3,
|
||||
]>
|
||||
|
||||
declare const MixedTestProto: MixedTestProto
|
||||
|
||||
class MixedTest extends MixedTestProto {}
|
||||
class MixedTest extends MixedTestProto {
|
||||
}
|
||||
|
||||
MixedTest.prototype
|
||||
new MixedTest().name
|
||||
new MixedTest().status.expiresAt
|
||||
|
||||
// type MixedTestTraitsProto = Class<
|
||||
// Extend2<TestTrait2, TestTrait1>,
|
||||
|
||||
66
src/util/class.ts
Normal file
66
src/util/class.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { AbstractClass } from "type-fest"
|
||||
|
||||
|
||||
/**
|
||||
* Represents an array of instances corresponding to the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesInstances<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? [InstanceType<Class>, ...ClassesInstances<Rest>]
|
||||
: never
|
||||
: never
|
||||
: []
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an intersection of instances of the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesInstancesIntersection<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? InstanceType<Class> & ClassesInstancesIntersection<Rest>
|
||||
: never
|
||||
: never
|
||||
: {}
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents the static members of a class.
|
||||
* @template Class - A class extending AbstractClass.
|
||||
*/
|
||||
export type StaticMembers<Class extends AbstractClass<any>> = (
|
||||
Omit<Class, "prototype">
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an array of static members corresponding to the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesStaticMembers<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? [StaticMembers<Class>, ...ClassesStaticMembers<Rest>]
|
||||
: never
|
||||
: never
|
||||
: []
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents an intersection of static members of the provided classes.
|
||||
* @template Classes - An array of classes extending AbstractClass.
|
||||
*/
|
||||
export type ClassesStaticMembersIntersection<Classes extends readonly AbstractClass<any>[]> = (
|
||||
Classes extends [infer Class, ...infer Rest]
|
||||
? Class extends AbstractClass<any>
|
||||
? Rest extends AbstractClass<any>[]
|
||||
? StaticMembers<Class> & ClassesStaticMembersIntersection<Rest>
|
||||
: never
|
||||
: never
|
||||
: {}
|
||||
)
|
||||
2
src/util/index.ts
Normal file
2
src/util/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./class"
|
||||
export * from "./inheritance"
|
||||
40
src/util/inheritance.ts
Normal file
40
src/util/inheritance.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Represents the common keys between two types.
|
||||
* @template A - The first type.
|
||||
* @template B - The second type.
|
||||
*/
|
||||
export type CommonKeys<A, B> = Extract<keyof A, keyof B>
|
||||
|
||||
/**
|
||||
* Merges an inheritance tree defined by an array of types, considering overrides.
|
||||
* @template T - An array of types representing the inheritance tree.
|
||||
*/
|
||||
export type MergeInheritanceTree<T extends readonly any[]> = (
|
||||
T extends [infer Super, infer Self, ...infer Rest]
|
||||
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? MergeInheritanceTree<[
|
||||
Omit<Super, CommonKeys<Self, Super>> & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: never
|
||||
: T extends [infer Self]
|
||||
? Self
|
||||
: void
|
||||
)
|
||||
|
||||
/**
|
||||
* Merges an inheritance tree defined by an array of types without allowing overrides.
|
||||
* @template T - An array of types representing the inheritance tree.
|
||||
*/
|
||||
export type MergeInheritanceTreeWithoutOverriding<T extends readonly any[]> = (
|
||||
T extends [infer Super, infer Self, ...infer Rest]
|
||||
? Pick<Self, CommonKeys<Self, Super>> extends Pick<Super, CommonKeys<Self, Super>>
|
||||
? MergeInheritanceTreeWithoutOverriding<[
|
||||
Super & Self,
|
||||
...Rest,
|
||||
]>
|
||||
: never
|
||||
: T extends [infer Self]
|
||||
? Self
|
||||
: void
|
||||
)
|
||||
Reference in New Issue
Block a user