在下面的示例中,Promise::then
访问者函数f
期望收到Example
。如果我明确传入一个缺少属性的格式错误的对象,我会收到类型错误。
但是,如果我只是将函数f
传递给.then(f)
,我就不会收到类型错误,即使打字稿知道T
中Promise<T>
的类型不是{ {1}}。
Example
我想知道为什么会发生这种情况,而且还有减轻Typescript中许可类型检查的技术。
如果双变量解释了这种现象,那么为什么在明确应用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)
})
时会出现类型错误?为什么他们对第一类函数与显式应用程序的规则不同?
答案 0 :(得分:2)
以下是我的想法:
p.then(f) // no type error (bad)
T
此处为{ id: number }
then()
采用{id: number} => U
Example => number
Example
可分配给{id: number}
,因此f
与then()
p.then(function(a : Example){
f(a)
})
兼容
让我再添加一个例子:
then()
由于同样的原因,它也可以正确编译:
Example => number
的参数类型为p.then(function(a){
f(a) // type error (good)
})
现在,为什么以下不能编译?
a
{id: number}
被推断为类型T
(因为最简单的事情是从p
的声明中将其视为f
< / LI>
{id: number}
使用不兼容的参数进行调用Example
无法分配给f
{id : number
需要(年龄缺失)。请注意,错误不是关于then()的参数,而是关于f()的参数。
现在,问题的第二部分:
减轻Typescript中的许可类型检查的技术。
如果你需要正确的类型检查,IMO Typescript不是一个选项,只要不健全但是&#34;可用&#34;类型检查仍然是其明确的设计目标之一。我听说Scala,Haskell和OCaml现在都有针对javacsript的编译器(但我不知道它们有多可用)。
问题的第三部分:
为什么他们对第一类函数与显式函数的规则不同 应用
因为在第一种情况下,参数是一个函数,而在第二种情况下(不编译),参数推断出类型then()
},这不是一个函数。 Bivariance是一个ad-hoc规则,仅当需要确定一个函数类型是否与另一个函数类型兼容时才适用。第一种情况是编译,因为一旦它根据规则看到then()
参数是正常的,它就不会进入@object = Object.include(:children).where(email:"test@example.com").first
实现来检查它在那里的实际工作方式。这就是造成它不健全的原因。