type A
&之间的输入关系是什么? type B
?
type A = {
a: string,
}
type B = {
a: string,
b?: string, // Same thing as —> "b: void | string"
}
// "-" means contravariant & write only & can accept supertypes
function test<-T: B>(value: T): void {}
declare var foo: A
test(foo)
根据https://flowtype.org/docs/variance.html#object-types ....
...对象之间的子类型关系来源于 他们的属性的子类型关系。
由于b?: string
与b: void | string
相同,这是否意味着我们正在比较两种不同的值类型(具有不同的属性)而没有关系?
我认为{ a: string }
是{ a: string, b: string }
的“超类型”似乎是合乎逻辑的,因为它是一种更具体的“价值类型”。 ......对{ a: string }
和{ a: string, b?: string }
也是如此。
答案 0 :(得分:2)
A&amp;类型之间的输入关系是什么? B型?
B
是A
的子类型。
您可以通过以下方式验证代码来验证这一点:
let b: B = {a:'bar', b:'wibble' };
let a: A = b;
//&#34; - &#34;意味着逆变&amp;只写&amp;可以接受超类型 功能测试&lt; -T:B&gt;(值:T):void {}
我认为这可能是你感到困惑的地方。
你不能从逆变值中读取,这意味着它作为函数的参数并没有多大意义。这不是一个任意的限制:如果你可能使用该值,你就无法对它做任何事情,因为你无法做出任何关于它的假设它是什么。
当我们谈论协变类型时,我们通常会讨论函数参数。使用该参数的函数通常可以忽略任何特化,因此处理任何子类型。我们从值使用者的角度指定差异,并且我们正在表达哪些提供商是兼容的。
逆变型通常是返回值。我们从提供程序的角度指定逆变返回类型。 超类型限制是通过声明此值的任何使用者不得指望我们提供的更具体的内容。例如,指定逆变返回类型Dog
意味着我会给你一些Dog
,但你可能不会假设更多:你可以像对待它一样对待它Mammal
或HasFur
,但你不能像Poodle
那样对待它,否则你会遇到问题,这就是类型检查员在这里所阻止的。 / p>