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)
})