以下代码中存在大量文本行的错误。当我将标记为line的箭头中的泛型的Y参数更改为数字或字符串等类型时,一切正常,编译后没有错误
问题1 - 它是编译器错误吗? 问题2 - 如何解决错误?
class channel<S,Y>{
public merge(...channels:channel<any, Y>[]) {
var ch = new channel<void, channel<any, Y>>(); // <---
var result = ch.flatMap(x => x);
return result;
}
public flatMap<R>(projector: (data: Y) => channel<any, R>): channel<Y, R> {
return null;
}
}
期望的结果类型是channel<any, Y>
,但编译器推断出不同的结果
错误讯息:
Error 1 Supplied parameters do not match any signature of call target:
Call signatures of types '(x: channel<any, channel<any, Y>>) => channel<any, channel<any, Y>>' and
'(data: channel<any, channel<any, Y>>) => channel<any, Y>' are incompatible:
Types 'channel<any, channel<any, Y>>' and 'channel<any, Y>' originating in infinitely expanding type reference have incompatible type arguments.
更新
public flatMap<R>(projector: (data: Y) => channel<any, R>): channel<any, R> {} // changed Y to any
public correct(...targets: channel<any, Y>[]) {
var ch = new channel<void, channel<any, Number>>().named('merge');
var result = ch.flatMap(x => x);
return result;
}
public incorrect(...targets: channel<any, Y>[]) {
var ch = new channel<void, channel<any, Y>>().named('merge'); // changed Number to Y
var result = ch.flatMap(x => x); // error
return result;
}
那里有些魔力。当我这样改变时,我得到(x:Number):Number => x
。但是当使用Y时,x是channel<any, channel<any,Y> >
答案 0 :(得分:1)
这可能是也可能不是类型推断的错误。这是一个复杂的例子,因此也许推断出泛型类型的原因。您可以通过在拨打R
flatMap<R>()
来提供帮助
var result = ch.flatMap<channel<any, Y>>(x => x);
或完全限定lambda
var result = ch.flatMap((x: channel<void, channel<any, Y>>): channel<void, channel<any, Y>> => {
return x;
});
我认为第一个看起来好多了。
答案 1 :(得分:1)
预期的结果类型为
channel<any, Y>
我不知道你是如何得出这个结论的。按照这个类和函数的定义:
ch
的类型为channel<void, channel<any, Y>>
(明确给出)
ch#S
= void
ch#Y
= channel<any, Y>
flatMap<R>
(明确指定)上调用时,channel<Y, R>
会返回channel<S, Y>
ch.flatMap
的调用,Y
= channel<any, Y>
(来自1.b)channel<channel<any, Y>, R>
(在Y
中替换为2中的定义)无论如何,因为你有一个无限扩展的泛型类型(参见TypeScript规范第3.8.7节),泛型类型推断必然是有限的(我相信问题实际上是不可判定的)。在这种情况下,最好的办法是手动指定类型参数,或者通过为x
提供类型注释为编译器提供额外的提示。