说我有这样的Flow typedef:
type ApiResponse = {
+foo?: { [string]: Object },
+bar?: { [string]: Object},
}
type FooApiResponse = {
foo: { [string] : Object }
}
具有以下签名的函数:
function does_not_accept(baz : ApiResponse) : void {
if(baz.foo) { console.log(baz.foo) }
}
function also_does_not_accept(baz: $Shape<ApiResponse>) : void {
if(baz.foo) { console.log(baz.foo) }
}
在参数位置调用其中一个函数FooApiResponse
失败。
第一个失败,bar
缺少属性错误(即使它是可选的。)
第二个失败,因为bar
是只读的(即使它从未被写入。)
如何编写一个接受ApiResponse
像$Supertype<ApiRsponse>
这样的参数类型签名有效 - 但我不明白为什么。如何在FooApiResponse
和ApiResponse
之间解决子/超级关系?这叫什么问题?我甚至不知道谷歌的词汇来解答这个问题。
答案 0 :(得分:0)
$Shape
和$Supertype
是实验性功能。如果他们没有做你想做的事情,或者希望他们做什么,可以考虑开个问题。
ApiResponse
没有超类型。它可能有效,因为您正在剥离已定义的属性 - 与使用{}
相同。我怀疑它打算用于使用extends
的类类型。
如果您将对象文字专门键入为FooApiResponse
,那么即使它们具有相同的形状,您也不希望它被ApiResponse
接受。您需要在参数类型上使用交集以允许它接受。
function accept(baz: ApiResponse | FooApiResponse) {}
我认为显示的Flow错误无益,所以可能会为此打开一个问题。指示只读的+
似乎也会混淆错误,但您未在FooApiResponse
定义中使用它,因此类型与foo
不兼容。< / p>