首页 > 解决方案 > TypeScript 覆盖现有值并强制执行字段值

问题描述

我一直在试图弄清楚如何扩展接口的可选值,这样如果一个字段设置为特定值,那么另一个字段必须存在,我无法弄清楚——这是怎么做到的?

目标是这样的:

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'
  }
]

标签: typescript

解决方案


所以解决方案是求和类型,您使用并集很接近,但我们需要定义判别式以允许 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
}

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


推荐阅读