I experiment a behavior that seems strange to me.
Let\'s consider the following sample (test it in Typescript playground):
abstract class FooAbstract {
This is all about how the type resolution works for the bar function:
bar() {
return this.foo.bar();
}
What is this.foo
? FOO
or more precisely, a class that extends FooAbstract
, because unlike the property foo
, bar
doesn't expose FOO
. The typing has to be determined before the actual type FOO is defined.
You would have to do something like this, if you really wanted to type it:
abstract class FooAbstract {
abstract bar(): T
}
class Foo extends FooAbstract<{ bar: string }> {
bar() {
return { bar: 'bar' };
}
}
class FooMaker, BAR> {
constructor(public foo: FOO) {}
bar():BAR {
return this.foo.bar();
}
baz = (): BAR => {
return this.foo.bar();
}
}
let foo = new Foo();
let result = foo.bar();
let foomaker = new FooMaker(new Foo);
let foo2 = foomaker.foo; // Type "Foo", OK
let result1 = foomaker.foo.bar(); // Type "{bar: string}", OK
let result2 = foomaker.bar(); // Type "{bar: string}", OK
let result3 = foomaker.baz(); // Type "{bar: string}", OK
And unfortunetly, you have to explicitly define the type of FooMaker, but you do prevent something like this:
let foomaker = new FooMaker(new Foo);