TypeScript覆盖现有值并强制执行字段值

时间:2019-10-23 08:33:19

标签: typescript

我一直在尝试找出如何扩展接口的可选值,这样,如果将一个字段设置为特定值,那么必须存在另一个字段 ,我无法弄清楚–怎么做完成了吗?

目标是:

  • 如果restrictedtrue,那么apiData仍然是可选的。
  • 如果设置了apiData,则restricted 必须设置为true
interface IRoute {
  path?: string
  restricted?: boolean
  exact?: boolean
  component: string
  layout?: string
  apiData?: string
}

interface IRouteWithData extends Omit<IRouteConfigItem, 'restricted apiData'> {
  restricted: true
  apiData: FC
}

type TRoute = IRouteWithData | IRouteConfigItem

const routeConfig: TRoute[] = [
  {
    path: '/foo',
    restricted: false, // this should be an error
    exact: true,
    component: 'something',
    apiData: 'some data'
  },
  {
    path: '/bar',
    restricted: true, // this is fine
    exact: true,
    component: 'something'
  }
]

1 个答案:

答案 0 :(得分:1)

因此,解决方案是求和类型,您通过使用并集进行了联系,但是我们需要定义判别式,以便允许TS推断出差异。

// all fields which are static in all sum elements
interface IRouteBase {
  path?: string
  exact?: boolean
  component: string
  layout?: string
}

// type representing that if restricted is true - apiData needs to be set
interface IRouteWithData extends IRouteBase  {
  restricted: true
  apiData: string
}
// type representing that if restricted is false- apiData is optional
interface IRouteMaybeData extends IRouteBase  {
  restricted: false
  apiData?: string
}

type TRoute = IRouteWithData | IRouteMaybeData;

// example use
const mustHaveApiData: TRoute = {
  component: 'component',
  restricted: true, // error you need to set apiData
}

const notNeedHaveApiData: TRoute = {
  component: 'component',
  restricted: false, // no error, apiData is optional
}

我的文章https://dev.to/macsikora/more-accurate-the-type-better-the-code-202l中包含有关使用总和类型的更多信息。享受吧!