Typescript derives different types when a static method is called from inside or outside a class

29 Views Asked by At

Can someone help me explain the behavior of typescript in this example. I have no idea what is going on here. Why is childProxy1.foo not resolved while childProxy2.foo is resolved correctly? Why is there a difference, when Factory.create() is called from inside the method Parent.create()?

type ProxyElements = {
    foo: string
}

class Parent<T> {
    protected proxyElements: T
    constructor(proxyElements: T) {
        this.proxyElements = proxyElements
    }
    
    public static create<R extends typeof Parent>(this: R){
        return this.getFactory().create()
    }
    
    public static getFactory<R extends typeof Parent>(this: R) {
        return new Factory(this) as Factory<R>;
    }
    
    public getProxy() {
        return <T & this> new Proxy(this, {
            get: (target, prop) => {
                if (prop in this.proxyElements) {
                    return this.proxyElements[prop]
                }
                return target[prop]
            }
        })
    }
}

class Child extends Parent<ProxyElements> {
    public childMethod() {
        return 'qux'
    }
}

class Factory<R> {
    protected classToInstantiate: new (proxyElements) => R

    constructor(classToInstantiate: new (proxyElements) => R) {
        this.classToInstantiate = classToInstantiate;
    }

    public create() {
        return (new this.classToInstantiate({foo: 'bar'}) as InstanceType<R>).getProxy()
    }
}

//public Factory<Child>.create(): T & Child extends {new(...args: any): infer R} ? R : any
const childProxy1 = Child.getFactory().create() 
childProxy1.foo //Unresolved variable foo 

//public static Parent<ProxyElements>.create<Child>(): ProxyElements & Child extends {new(...args: any): infer R} ? R : any
const childProxy2 = Child.create()
childProxy2.foo //Correctly resolved foo

I think in both cases the result should be the same. Or am I missing something important here?

0

There are 0 best solutions below