gpt4 book ai didi

javascript - 没有标签的不相交联合

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:26:12 25 4
gpt4 key购买 nike

我有这种情况,没有办法有意义地改变数据结构。所以我不能添加标签。有没有办法区分没有标签的类型?我试过 ducktyping,但它不起作用。看我的example

type Result = Done | Error; // a disjoint union type with two cases
type Done = { count: number }
type Error = { message: string }

const doSomethingWithDone = (obj: Done) => {/*...*/}
const doSomethingWithError = (obj: Error) => {/*...*/}

const f = (result: Result) => {
if (result.count) {
doSomethingWithDone(result)
} else {
doSomethingWithError(result)
}
}

错误是:

 5: const doSomethingWithDone = (obj: Done) => {/*...*/}
^ property `count`. Property not found in
10: doSomethingWithDone(result)
^ object type
6: const doSomethingWithError = (obj: Error) => {/*...*/}
^ property `message`. Property not found in
12: doSomethingWithError(result)
^ object type

最佳答案

Flow 不像不相交的联合那样优雅地支持这种事情。但是,确切的类型可以提供帮助。你的例子中的问题是我可以做

const x: Error = {message: 'foo', count: 'bar'};
f(x);

赋值是有效的,因为我的对象字面量满足 x 接口(interface)。因此,虽然您知道如果某个东西是 Error,它具有 message 属性,但您不知道它还有哪些其他属性。因此,检查 count 属性是否存在并不能证明您拥有类型为 Done 的有效对象。

精确类型在这里可以提供帮助:

type Result = Done | Error; // a disjoint union type with two cases
type Done = {| count: number |}
type Error = {| message: string |}

const doSomethingWithDone = (obj: Done) => {/*...*/}
const doSomethingWithError = (obj: Error) => {/*...*/}

const f = (result: Result) => {
if (result.count) {
doSomethingWithDone(result)
} else if (result.message) {
doSomethingWithError(result)
}
}

// Expected error. Since Error is an exact type, the count property is not allowed
const x: Error = {message: 'foo', count: 'bar'};
f(x);

( tryflow link )

请注意,除了使类型准确之外,我还必须将您的 else 更改为 else if。显然,使用精确类型的缺点是您的对象不能有无关的字段。但是,如果您绝对不能添加鉴别器字段来使用不相交的联合,我认为这是最好的选择。

关于javascript - 没有标签的不相交联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42247200/

25 4 0