[英]TypeScript utility type over a discriminated union type
給定一個像這樣有區別的聯合類型:
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)
您可以使用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)
最詳細的解決方案是:
type Discriminate<TUnion, TDiscriminant> =
TUnion extends {name: TDiscriminant} ? TUnion : never
type HomeMember = Discriminate<Route, 'Home'>;
type PageMember = Discriminate<Route, 'Page'>;
我們還可以使用現有的實用程序類型 Extract ,它將執行條件類型以供使用:
type Discriminate<TUnion, TDiscriminant> = Extract<TUnion, {name: TDiscriminant}>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.