diff --git a/src/class.ts b/src/class.ts deleted file mode 100644 index 8cff9e9..0000000 --- a/src/class.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { AbstractClass } from "type-fest" - - -/** - * Copies all own properties and methods (excluding "length" and "prototype") of one class to another class. - * - * @param from The class whose properties and methods are to be copied. - * @param to The class to which the properties and methods are to be copied. - */ -export function copyClassProperties( - from: AbstractClass, - to: AbstractClass, -) { - Object.getOwnPropertyNames(from).forEach(name => { - if (name === "length" - || name === "prototype" - ) - return - - Object.defineProperty( - to, - name, - Object.getOwnPropertyDescriptor(from, name) || Object.create(null), - ) - }) - - Object.getOwnPropertyNames(from.prototype).forEach(name => { - Object.defineProperty( - to.prototype, - name, - Object.getOwnPropertyDescriptor(from.prototype, name) || Object.create(null), - ) - }) -} - -export const flattenClass = < - C extends AbstractClass ->(class_: C) => - getInheritanceHierarchy(class_) - .reduce((flattened, current) => { - copyClassProperties(current, flattened) - return flattened - }, class {}) as C - -/** - * Returns an array of classes representing the inheritance hierarchy of a given class constructor. The array includes the given class constructor itself and all its parent classes in the order of inheritance. - * - * @param class_ The class constructor for which to generate the inheritance hierarchy. - * @returns An array of class constructors representing the inheritance hierarchy of `Class`. - */ -export function getInheritanceHierarchy( - class_: AbstractClass -): AbstractClass[] { - const parent = Object.getPrototypeOf(class_) - - return isClass(parent) - ? [...getInheritanceHierarchy(parent), class_] - : [class_] -} - -/** - * Determines whether a given value is a class constructor or not by checking if its `toString` method returns a string matching the pattern of a class definition. - * - * @param el The value to check for class constructor status. - * @returns A boolean indicating whether `el` is a class constructor or not. - */ -export const isClass = (el: { toString: () => string }) => - Boolean(el.toString().match(/^class(?: [.\S]+)?(?: extends [.\S]+)? {[\s\S]*}$/)) diff --git a/src/index.ts b/src/index.ts index 46c8360..d46d244 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1 @@ -export * from "./class" export * from "./trait" -export * from "./utils" diff --git a/src/trait.ts b/src/trait.ts index 021d69a..22f199d 100644 --- a/src/trait.ts +++ b/src/trait.ts @@ -1,6 +1,5 @@ import { AbstractClass, Class, UnionToIntersection } from "type-fest" -import { copyClassProperties, flattenClass } from "./class" -import { StaticMembers } from "./utils" +import { StaticMembers, copyClassProperties, flattenClass } from "./util/class" export type Trait = diff --git a/src/util/class.ts b/src/util/class.ts new file mode 100644 index 0000000..671ff45 --- /dev/null +++ b/src/util/class.ts @@ -0,0 +1,90 @@ +import { AbstractClass } from "type-fest" + + +/** + * Represents the static members of a class. + * + * @template C - The type of the class for which static members are extracted. + * @typeparam The static members of the class. + */ +export type StaticMembers = Pick + + +/** + * Copies properties from one class to another, including static and prototype properties. + * + * @param from - The source class to copy properties from. + * @param to - The destination class to copy properties to. + */ +export function copyClassProperties( + from: AbstractClass, + to: AbstractClass, +) { + Object.getOwnPropertyNames(from).forEach(name => { + if (name === "length" + || name === "prototype" + ) + return + + Object.defineProperty( + to, + name, + Object.getOwnPropertyDescriptor(from, name) || Object.create(null), + ) + }) + + Object.getOwnPropertyNames(from.prototype).forEach(name => { + Object.defineProperty( + to.prototype, + name, + Object.getOwnPropertyDescriptor(from.prototype, name) || Object.create(null), + ) + }) +} + + +/** + * Flattens the inheritance hierarchy of a given class by copying all properties + * from its superclass chain into a single object. + * + * @template C - The type of the class to be flattened, extending AbstractClass. + * @param C - The class to be flattened. + * @returns A new class with properties flattened from the entire inheritance hierarchy. + */ +export function flattenClass< + C extends AbstractClass +>(class_: C) { + return getInheritanceHierarchy(class_) + .reduce((flattened, current) => { + copyClassProperties(current, flattened) + return flattened + }, class {}) as C +} + + +/** + * Retrieves the inheritance hierarchy of a given class, including itself. + * + * @param class_ - The class for which the inheritance hierarchy is retrieved. + * @returns An array representing the inheritance hierarchy. + */ +export function getInheritanceHierarchy( + class_: AbstractClass +): AbstractClass[] { + const parent = Object.getPrototypeOf(class_) + + return isClass(parent) + ? [...getInheritanceHierarchy(parent), class_] + : [class_] +} + + +/** + * Checks if a given element appears to be a class based on its string representation. + * + * @param el - The element to check for being a class. + * @returns `true` if the element is likely a class; otherwise, `false`. + */ +export function isClass(el: { toString: () => string }) { + return Boolean(el.toString().match(/^class(?: [.\S]+)?(?: extends [.\S]+)? {[\s\S]*}$/)) +} diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 87f5f52..0000000 --- a/src/utils.ts +++ /dev/null @@ -1 +0,0 @@ -export type StaticMembers = Pick