首页 > 解决方案 > 关于 TypeScript 互斥类型的几个问题

问题描述

我希望option有一个path属性或一个children属性,但不是两者都有。并且在使用过程中可以正确导出。</p>

首先,我这样做:

type Option = {name: string, path: string} | {name: string, children: Option[]}
declare const option: Option
option.path // Property 'path' does not exist on type 'Test'

在线测试

然后,我使用这种方式: Typescript 是否支持互斥类型?

type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;


type Option = {name: string} & XOR<{path: string}, {children: Option[]}>

// const option: Option = {name: '1', path: ''} // ok
// const option: Option = {name: '1', children: []} // ok
// const option: Option = {name: '1', value: '', children: []} // error, but ok

declare const option: Option

if (option.children) option.children.concat()
else option.path.toLocaleUpperCase()

if (option.path) option.path.toLocaleUpperCase()
else option.children.concat() // why ?!

在线测试

那么,我想知道以上两个错误的原因是什么?以及如何修复它们?

标签: typescript

解决方案


type Option = {name: string, path?: never, children: Option[]} | {name: string, path: string, children?: never};


declare const option: Option

if (option.children) option.children.concat()
else option.path.toLocaleUpperCase()

if (option.path) option.path.toLocaleUpperCase()
else option.children.concat() //fixed

希望这可以帮助

编辑您想要区分联合类型,本质上是它的真实名称。您可以在此处找到等效的打字稿文档 https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions


推荐阅读