【发布时间】:2020-11-03 04:53:16
【问题描述】:
有没有办法帮助编译器推断如下内容:
class Base<T> {
children(... children: (A<any> | B<T>)[]) { return this }
onVisit(handler:(context: T)=>void) { return this }
}
class A<T> extends Base<T> {
constructor( public context: T ) { super() }
}
class B<T> extends Base<T> {}
const foo = new A({ bar: 1 })
.children(
new A({baz:2}).onVisit(({baz})=>{}),
new B().onVisit(({bar})=>{}) // Fails here because it infers that the instance as type B<unknown> instead of B<{bar:number}>
)
这似乎不是因为编译器无法从调用函数中绘制一些上下文,因为这可行:
function f1<T>(p: T, ...h: ((p:T) => void)[]) { }
function f2<T>(h: (p: T) => void) { return h }
f1({ a: 1 },
f2((p) => { console.log(p.a) }),
)
我可能完全糊涂了(很可能),但似乎后者是否有效,前者也应该如此。
【问题讨论】:
-
这是因为当您创建
new B()时,这将创建一个 B。在查看 onVisit之前,编译器将首先对此进行分析。所以创建B时需要提供type参数。 -
我是这么想的,但是为什么编译器不将第二个例子中的函数实例化为
f2<unknown>呢?构造函数是否因某种原因而被区别对待,还是我误解了不同场景之间的区别? -
您的第一个示例中的构造函数没有参数,因此无法推断类型。在您的第二个示例中,推断出
f2的参数,因为在f1的定义中,您定义了两个参数的T相同。 -
@StéphaneVeyret: facepalm: 对。当然。谢谢。