簡體   English   中英

基於可區分聯合類型的 TypeScript 實用程序類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM