将mayBe类型与对象文字的可选道具混合
type Response = {
data?: string;
}
function length(): ?string {
return undefined;
}
function test(): Response {
const data = length()
return {
data
}
}
12: data ^ Cannot return object literal because null or undefined [1] is incompatible with string [2] in property `data`.
References:
5: function length(): ?string {
^ [1]
2: data?: string;
^ [2]
根据MayBe types和Object Types的流程文档,我不确定为什么会出现错误,有没有办法解决这个问题?
也许类型和可选对象属性在流程中并不完全相同,并且并不总是兼容的。
首先让我们看一下Maybe Types的doc链接:
也许类型接受提供的类型以及
null
或undefined
。所以?number
意味着number
,null
或undefined
。
所以?number
基本上是number | null | undefined
。
现在让我们看一下你的对象类型链接from the docs:
除了它们的设定值类型,这些可选属性可以是
void
或完全省略。但是,他们不能是null
。
因此,如果我们做type Response { data?: string }
然后response.data
基本上是string | void
。请注意,void
是与null
完全分开的类型。
那么现在让我们分解你的例子:
type Response = {
data?: string; // void | string
}
function length(): ?string { // void | string | null
return undefined;
}
function test(): Response {
const data = length()
// at this point, as far as flow knows, `data` can be `void`, `string`, or
// `null`, and we're trying to set it as the `data` property on our
// `Response` type which expects a `void` or a `string`, and does not
// expect a `null`.
return {
data
}
}
所以基本上,Response.data
期待void | string
,你试图用void | string | null
设置它。类型必须在某处更改才能成功完成操作。有多种可能的方法:
length
return value to be more specific. Probably the simplest:function length(): void | string {
return undefined;
}
我们已经删除了data
成为null
的可能性,所以没有更多的类型错误。
Response.data
a maybe type如果它们都是类型,问题就会消失。可能的最小变化是这一个:
type Response = {
data?: string | null;
}
我们刚刚增加了Response.data
成为null
的可能性。现在它可以接受length
的返回类型,类型匹配,没有错误。但这有点令人困惑,将null
与可选属性相结合。我们可以这样做:
type Response = {
data: ?string,
}
function test(): Response {
const data = length()
// at this point response.data is `void`
const response = {};
if (data) {
// data is now a `number`, not `number | void | null`
response.data = data;
}
// response.data is now `number | void` (not `null`)
return response
}
决定使用哪些选项几乎完全取决于最佳API,无论遇到什么问题,还可能选择如何处理可选类型和一般类型。