Node.js/TypeScript

[TypeScript] mixin

BlockHead 2023. 2. 27. 16:44
comment

- 저장용

 

 

global.d.ts
type Constructor<T = object> = new (...args: any[]) => T;

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;

 

mixin.ts
function applyMixin<D, T>(derived: Constructor<D>, target: Constructor<T>) {
    const proto = Object.getPrototypeOf(target);

    Object.getOwnPropertyNames(proto).forEach((name) => {
        Reflect.defineProperty(
            derived.prototype,
            name,
            Reflect.getOwnPropertyDescriptor(proto, name) || Object.create(null),
        );
    });
}

export function mixin<D, T>(derived: Constructor<D>, target: Constructor<T>): Constructor<D & T>;
export function mixin<T extends Constructor[]>(...constructors: [...T]): Constructor<UnionToIntersection<InstanceType<T[number]>>> {
    const derived = constructors[0];

    if (!derived) throw new Error('1 argument required, but only 0 present.');

    for (let i = 1; i < constructors.length; i++) {
        const target = constructors[i];
        applyMixin(derived, target);
    }

    return derived as any;
}

 

 

 

Reference