泛型错误的类型推断

时间:2014-05-05 13:51:39

标签: types typescript

以下代码中存在大量文本行的错误。当我将标记为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> >

2 个答案:

答案 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>

我不知道你是如何得出这个结论的。按照这个类和函数的定义:

  1. ch的类型为channel<void, channel<any, Y>>(明确给出)
    • ch#S = void
    • ch#Y = channel<any, Y>
  2. flatMap<R>(明确指定)上调用时,
  3. channel<Y, R>会返回channel<S, Y>
  4. 对于ch.flatMap的调用,Y = channel<any, Y>(来自1.b)
  5. 因此返回类型为channel<channel<any, Y>, R>(在Y中替换为2中的定义)
  6. 无论如何,因为你有一个无限扩展的泛型类型(参见TypeScript规范第3.8.7节),泛型类型推断必然是有限的(我相信问题实际上是不可判定的)。在这种情况下,最好的办法是手动指定类型参数,或者通过为x提供类型注释为编译器提供额外的提示。