为什么 `{ a: string }` 不能流入 `{ a?: string }`
Why can't `{ a: string }` flow into `{ a?: string }`
给定对象类型 A
和 B
除了 A
的属性是可选的之外它们是相同的......为什么不能 B
就地使用A
在哪里被接受?
type A = { a?: string };
type B = { a: string };
const x: B = { a:'…' };
// …string is incompatible with undefined in property `a`
(x: A)
我认为 Flow 试图警告如果 x
被输入为 A
那么它可能会被修改以使其仍然满足 A
的类型定义但是不满足 B
的类型定义。例如,您可以删除 a
属性 if x: A
,这将违反 B
.
我通过创建 A
的新 "read only" 版本并将 x
转换为它来测试它。
type Required = { a: string};
type Optional = { a?: string };
type ReadOnlyOptional = $ReadOnly<Optional>;
const x: Required = { a: '' };
(x: Optional); // error
(x: ReadOnlyOptional); // no error!
为了能够执行类型转换,要转换的类型必须包含在当前类型的类型定义中。
在这种情况下
type A = { a?: string };
type B = { a: string };
无法转换这些类型,无论是 A > B 还是 B > A,因为它的类型定义不匹配。
如果您定义了下一个类型:
type A = { a?: string };
type B = { a?: string, b: number };
你可以从类型 B 转换为类型 A
const x: B = { a: '...', b: 1 };
(x: A)
const x: B = { b: 1 };
(x: A)
这些都是有效的,因为类型 A 包含在类型 B 中。
但是您不能从类型 A 转换为类型 B,因为类型 A 的定义不包含在类型 B 中。
const x: A = { a: '...' };
(x: B)
此转换失败。
给定对象类型 A
和 B
除了 A
的属性是可选的之外它们是相同的......为什么不能 B
就地使用A
在哪里被接受?
type A = { a?: string };
type B = { a: string };
const x: B = { a:'…' };
// …string is incompatible with undefined in property `a`
(x: A)
我认为 Flow 试图警告如果 x
被输入为 A
那么它可能会被修改以使其仍然满足 A
的类型定义但是不满足 B
的类型定义。例如,您可以删除 a
属性 if x: A
,这将违反 B
.
我通过创建 A
的新 "read only" 版本并将 x
转换为它来测试它。
type Required = { a: string};
type Optional = { a?: string };
type ReadOnlyOptional = $ReadOnly<Optional>;
const x: Required = { a: '' };
(x: Optional); // error
(x: ReadOnlyOptional); // no error!
为了能够执行类型转换,要转换的类型必须包含在当前类型的类型定义中。
在这种情况下
type A = { a?: string };
type B = { a: string };
无法转换这些类型,无论是 A > B 还是 B > A,因为它的类型定义不匹配。
如果您定义了下一个类型:
type A = { a?: string };
type B = { a?: string, b: number };
你可以从类型 B 转换为类型 A
const x: B = { a: '...', b: 1 };
(x: A)
const x: B = { b: 1 };
(x: A)
这些都是有效的,因为类型 A 包含在类型 B 中。
但是您不能从类型 A 转换为类型 B,因为类型 A 的定义不包含在类型 B 中。
const x: A = { a: '...' };
(x: B)
此转换失败。