What is causing this issue and how should it be resolved?
class A {
constructor() {
console.log('constructin A')
}
public someMethod = (x: string) => {
console.log(x)
}
}
class B {
private myA: A
constructor(a: A) {
console.log('constructin B')
this.myA = a
}
// Fails with "Uncaught TypeError: Cannot read property 'someMethod' of undefined"
anotherMethod = this.myA.someMethod;
}
const a = new A()
const b = new B(a)
b.anotherMethod('hello')
Additional Information:
- This issue persists even when using plain JavaScript instead of TypeScript.
- The preference for the syntax
overanotherMethod = this.myA.someMethod
stems from complex type annotations onanotherMethod = (x: string) => { this.myA.someMethod(x) }
someMethod
that are impractical to duplicate onanotherMethod
.
UPDATE (19.06.2020) - 'with decoupling'
The explanations provided in response to this query, including comments such as this, shed light on why the original syntax fails to function. Regarding potential solutions:
Decoupling A and B: While not explicitly stated initially, the objective behind having B
utilize a method from A
is to establish a level of separation between them. In practical scenarios, different instances of A
adhere to a common interface comprising someMethod
implementations tailored to their specific requirements. The desired outcome is for B
to interact with someMethod
offered by any given A
instance without delving into implementation nuances. The accepted resolution comprehends this intention effectively through detailed code examples. It presents an optimal, seamless syntax devoid of pitfalls for this particular scenario. For quick reference, refer to the accepted answer, specifically:
public anotherMethod(...args: Parameters<A['someMethod']>): ReturnType<A['someMethod']> {
return this.myA.someMethod(...args);
}
In cases where decoupling is unnecessary, this outlined approach may prove adequate.