Generics 为什么第一类函数没有在typescript中进行类型检查?

Generics 为什么第一类函数没有在typescript中进行类型检查?,generics,typescript,functional-programming,Generics,Typescript,Functional Programming,在下面的示例中,Promise::thenvisitor函数f期望收到示例。如果我显式传入一个缺少属性的格式错误的对象,我会得到一个类型错误 但是,如果我只是将函数f传递给,那么(f)我不会得到类型错误,即使typescript知道Promise中T的类型不是示例 interface Example { id: number age: number } interface Promise <T> { then <U> ( f: ( a: T) =

在下面的示例中,
Promise::then
visitor函数
f
期望收到
示例
。如果我显式传入一个缺少属性的格式错误的对象,我会得到一个类型错误

但是,如果我只是将函数
f
传递给
,那么(f)
我不会得到类型错误,即使typescript知道
Promise
T
的类型不是
示例

interface Example {
    id: number
    age: number
}

interface Promise <T> {
    then <U> ( f: ( a: T) => U ) : Promise<U> 
}

function f(s:Example){
    return s.age
}

var p : Promise<{ id: number }>

p.then(f) // no type error (bad)

p.then(function(a){
    f(a) // type error (good)
})
接口示例{
身份证号码
年龄:数目
}
接口承诺{
然后(f:(a:T)=>U):承诺
}
函数f(s:示例){
回归美国时代
}
var p:承诺
p、 然后(f)//没有类型错误(错误)
p、 然后(函数(a){
f(a)//类型错误(良好)
})
我想知道为什么会发生这种情况,还有一些技术可以减轻Typescript中的许可类型检查


如果双变量解释了这种现象,那么当显式应用
f
时,为什么会出现类型错误?为什么第一类函数和显式应用程序的规则不同?

以下是我认为正在发生的事情:

  • T
    这里是
    {id:number}
  • then()
    声明为接受
    {id:number}=>U类型的参数
  • f具有类型
    示例=>编号
  • 示例
    可分配给
    {id:number}
    ,因此
    f
    then()
    的参数类型兼容,因为
让我再举一个例子:

p.then(function(a : Example){
    f(a)
})
出于同样的原因,它编译时也不会出错:

  • then()
    的参数具有类型
    Example=>number
现在,为什么不编译下面的代码

  • 我猜
    a
    被推断为具有类型
    {id:number}
    (因为最简单的方法是从
    p
    的声明中将其视为
    T
  • 所以这里用不兼容的参数调用
    f
  • 因为
    {id:number}
    不能分配给
    f
    需要的
    示例
    (缺少年龄)
请注意,该错误与then()的参数无关,而是与f()的参数有关

现在,关于问题的第二部分:

减轻Typescript中允许类型检查的技术

如果您需要正确的类型检查,只要不健全但“可用”的类型检查仍然是其明确的设计目标之一,IMO Typescript就不是一个选项。我听说Scala、Haskell和OCaml现在都有针对JavaCScript的编译器(但我不知道它们有多有用)

问题的第三部分:

为什么第一类函数和显式函数的规则不同 申请


因为在第一种情况下,参数是一个函数,而在第二种情况下(不编译),参数具有推断类型
{id:number
},它不是函数。双变量是一种特殊规则,仅当需要确定一种函数类型是否与另一种函数类型兼容时才适用。第一个案例是编译的,因为一旦它看到
then()
参数根据规则是正确的,它就不会进入
then()
实现来检查它在那里实际如何工作。这就是问题所在。

可能的重复:。参见@artem,我不认为这是由双变量引起的。但我可能错了。你的回答很有帮助,但我仍然不明白为什么二元变量特别适用于一级函数。如果双变量解释了这种现象,那么显式应用程序应该没有类型错误,应该应用相同的规则。当Typescript是一类函数时,它的泛型是否无法推断出它的结构?我在答案中添加了另一部分试图解释它。错误是由于非函数参数的参数类型不正确造成的,因此双变量不适用。
p.then(function(a : Example){
    f(a)
})
p.then(function(a){
    f(a) // type error (good)
})