我尝试了一种对我来说似乎很奇怪的行为。
让我们考虑以下示例(在 Typescript Playground 中测试它):
abstract class FooAbstract {
abstract bar() {}
}
class Foo extends FooAbstract {
bar() {
return { bar: 'bar' };
}
}
class FooMaker<FOO extends FooAbstract> {
constructor(public foo: FOO) {}
bar() {
return this.foo.bar();
}
baz = () => {
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 "{}", ???
let result3 = foomaker.baz(); // I've seen comments about using a lambda... Not better
result2
and result3
像摘要一样输入bar
功能 ({}
)。看起来this
没有被解析为具体类Foo
但作为抽象类FooAbstract
。而类型foo2
表明该类foo
属性已正确解析。
到底是怎么回事?我是否以错误的方式做事?
update
事后看来,这个案例可以重新表述如下(在 Typescript Playground 中测试它):
class Foo {
bar() {
return { bar: 'bar' };
}
getThis(): this {
return this
}
}
class Wrapper {
bar<FOO extends { bar(): {} }>(foo:FOO) {
return foo.bar();
}
}
let wrapper = new Wrapper();
let result = (new Foo()).bar();
let result2 = wrapper.bar(new Foo());
result
有类型{bar:string}
result2
有类型{}
(来自界面)。
wrapper.bar
有类型Wrapper.bar<Foo>(foo: Foo): {}
通过这个示例,可以更清楚地看出,即使知道FOO
键入为Foo
, 打字稿 uses FOO
定义而不是其显式类型bar
返回类型。
update 2
好吧,在与打字作斗争的同时,我想我已经升级了。这个概念确实是隐式类型打字稿即使推导了类型,也不遵循任何继承模型。嗯,我还是想知道why or 它会改变吗,但我必须应对“就是这样”。所以在这种情况下,类型必须是显式的。
我找到了一种更简单的方法来编写他的示例(在 Typescript 游乐场尝试一下):
abstract class FooAbstract {
abstract bar(): {}
}
class Foo extends FooAbstract {
bar() {
return { bar: 'bar' };
}
}
class FooMaker<FOO extends FooAbstract, BAR> {
constructor(public foo: FOO & { bar: () => BAR } ) {
}
bar():BAR {
return this.foo.bar() as BAR;
}
}
let foomaker = new FooMaker(new Foo());
let result = foomaker.bar();
result
获取类型{bar:string}
并且无需到处放置泛型。里面的东西FooMaker.constructor
通过使用泛型引用接口,参数类型可以变得更清晰。