给出这样的可区分联合类型:
type HomeRoute = { name: 'Home' };
type PageRoute = { name: 'Page'; id: number };
type SearchRoute = { name: 'Search'; text: string; limit?: number };
type Route = HomeRoute | PageRoute | SearchRoute;
我想要一个采用联合类型及其判别式(这里是名称成员的类型:"Home" | "Page" | "Search"
)并返回匹配大小写的实用程序类型:
type Discriminate<TUnion, TDiscriminant> = ???
type TestHome = Discriminate<Route, 'Home'>; // Expecting "HomeRoute" (structure)
type TestPage = Discriminate<Route, 'Page'>; // Expecting "PageRoute" (structure)
答案 0 :(得分:2)
您可以使用Extract
预定义的条件类型:
type HomeRoute = { name: 'Home' };
type PageRoute = { name: 'Page'; id: number };
type SearchRoute = { name: 'Search'; text: string; limit?: number };
type Route = HomeRoute | PageRoute | SearchRoute;
type TestHome = Extract<Route, { name: 'Home' }>;
type TestPage = Extract<Route, { name: 'Page' }>;
您还可以创建Discriminate
的通用版本,但不确定是否值得,因为您也需要该字段:
type Discriminate<TUnion, TField extends PropertyKey, TDiscriminant> = Extract<TUnion, Record<TField, TDiscriminant>>
type TestHome = Discriminate<Route, 'name', 'Home'>; // Expecting "HomeRoute" (structure)
type TestPage = Discriminate<Route, 'name', 'Page'>; // Expecting "PageRoute" (structure)
答案 1 :(得分:1)
最冗长的解决方案是:
type Discriminate<TUnion, TDiscriminant> =
TUnion extends {name: TDiscriminant} ? TUnion : never
type HomeMember = Discriminate<Route, 'Home'>;
type PageMember = Discriminate<Route, 'Page'>;
我们还可以使用现有的实用程序类型提取,它将提取条件类型以供使用:
type Discriminate<TUnion, TDiscriminant> = Extract<TUnion, {name: TDiscriminant}>