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?