关于 TypeScript 互斥锁类型的几个问题



我希望option具有path属性或children属性,但不能同时具有两者。并且可以在使用过程中正确推导。

首先,我这样做:

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 ?!

在线测试

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

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

最新更新