使用联合类型时,通常最简单的做法是使用带标签的联合创建ADT。但是,有时这是不可能的。
一个典型的例子是React Router的<Route/>
组件。这里,有三个可选的道具:<Route/>
,component
和render
,但是必须有1个,并且正好传递了这3个中的1个。]
为简单起见,我在这里缩减了类型,但是当前发布的类型看起来像这样:
应该更像这样:children
他们应该真的
interface Route { render?: string component?: string children?: string someOtherProps?: any }
所以,有两个问题:
interface BetterRouteRender extends Route {
render: string
component?: undefined
children?: undefined
}
interface BetterRouteComponent extends Route {
render?: undefined
component: string
chldren?: undefined
}
interface BetterRouteChildren extends Route {
render?: undefined
component?: undefined
Children: string
}
type BetterRoute =
| BetterRouteRender
| BetterRouteComponent
| BetterRouteChildren
const invalidRouteBecauseEmpty: BetterRoute = {}
const invalidRouteBecauseDupe: BetterRoute = { render: 'render', component: 'component' }
const validRoute: BetterRoute = { render: 'render' }
...将使用类似type BetterOptionalTypeConstructor<T, KS extends Array<keyof T>> = unknown
的方式,并吐出上面显示的BetterOptionalTypeConstructor<Route, ['render', 'component', 'children']>
类型。
我还没有为此付出很多努力,但是据我所知,Typescript目前似乎不支持“映射联合类型”。在这方面的任何见识将不胜感激!
使用联合类型时,通常最简单的做法是使用带标签的联合创建ADT。但是,有时这是不可能的。一个典型的例子是React Router的
在通过@Mickey发布的链接进行了一些研究之后,我想到了以下解决方案。具体来说,BetterRoute
很有启发性。