簡體   English   中英

將有區別的聯盟划分為有和沒有財產的類型的方法

[英]Way to segment discriminated union into types with and without property

讓我們說我有一個像這樣的歧視聯盟:

type Route = HomeRoute | ProfileRoute | BlogRoute;


type HomeRoute = {
  route: '/home'
}

type ProfileRoute = {
  route: '/profile/:userId',
  params: {
    userId: string;
  }
}

type BlogRoute = {
  route: '/blog/:teamId',
  params: {
    teamId: string;
  }
}

我有一個在Route對象上運行的函數,如果它們有params,則有一些可選的邏輯:

function processRoute(route: Route) {
  if ('params' in route) {
    const { params } = route; // <-- this errors
  }
}

似乎沒有辦法(我可以看到)檢查params而不添加any注釋...

function paramsInRoute(route: any): route is { params: {[key: string]: string} } {
  return ('params' in route);
}

function processRoute(route: Route) {
  if ('params' in route) {
    const { params } = route; // <-- this errors
  }

  if (paramsInRoute(route)) {
    const { params } = route; // <-- this typechecks
  }
}

有沒有辦法在沒有強制轉換的情況下(在paramsInRoute的參數中)執行上述操作?

游樂場鏈接

我個人非常樂意使用您擁有的型號后衛:

function paramsInRoute(route: any): route is { params: {[key: string]: string} } {
  return ('params' in route);
}

因為TypeScript肯定會將傳入的Route對象縮小為ProfileRoute | BlogRoute

if (paramsInRoute(route)) {
    const notHomeRouteAnymore: ProfileRoute | BlogRoute = route; // no error
}

但如果你擔心有人這樣做:

const notRoute = "This is not a route";
if (paramsInRoute(notRoute)) { notRoute.params.oops = 'what' };

然后你可以這樣做:

function paramsInRoute(route: Route): route is Route & { params: {[key: string]: string} } {
  return ('params' in route);
}

它做同樣的縮小但防止錯誤的電話:

paramsInRoute(notRoute); // error

希望有所幫助; 祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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