Skip to content

Instantly share code, notes, and snippets.

const fn = <
T extends typeof Base,
Instance extends InstanceType<T>
>(Cls: T, prop: keyof Instance,
) => new Cls()[prop];
class Base { }
function fn<T extends typeof Base>(
Cls: T,
prop: keyof InstanceType<T>,
) {
return (new Cls())[prop]; // error
}
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
type ClassType = new (...args: any[]) => any;
// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
function Mixin<T extends ClassType, R extends T[]>(...classRefs: [...R]):
new (...args: any[]) => UnionToIntersection<InstanceType<[...R][number]>> {
type ClassType = new (...args: any[]) => any;
function Mixin<T extends ClassType, R extends T[]>(...classRefs: [...R]): InstanceType<R[number]> {
return null as any
}
class Foo {
foo() { }
}
// added extra R generic
function Mixin<T extends ClassType, R extends T[]>(...classRefs: [...R]){
return merge(class { }, ...classRefs);
}
function Mixin<T extends ClassType>(...classRefs: T[]) {
return merge(class { }, ...classRefs);
}
type ClassType = new (...args: any[]) => any;
function merge(derived: ClassType, ...classRefs: ClassType[]) {
classRefs.forEach(classRef => {
Object.getOwnPropertyNames(classRef.prototype).forEach(name => {
const descriptor = Object.getOwnPropertyDescriptor(classRef.prototype, name)
// just add condition statement
if (name !== 'constructor' && descriptor) {
Object.defineProperty(
derived.prototype,
type ClassType = new (...args: any[]) => any;
// add ClassType
function merge(derived: ClassType, ...classRefs: ClassType[]) {
// same logic from previous version
return derived
}
type ClassType = new (...args: any[]) => any;