用ts定義一個(gè)屬性二選一的對(duì)象

當(dāng)我們不單單要明確定義參數(shù)的類型,而且如果參數(shù)為 object 的話,還有可能出現(xiàn) object 里面某兩個(gè)屬性是沖突,只能“二選一”的情況

interface IMyParams {
  a: number;
  b: number;
}

// 如果我們需要將一個(gè)參數(shù)定義為對(duì)象,并且其屬性 a 或者 b 必須要傳遞一個(gè)的話
function Table(params: IMyParams): number{
  if (params.a) {
    console.log(params.a + 1);
  } else {
    console.log(params.b + 1);
  }
}

下面定義了一個(gè) EitherOr 的類型來(lái)處理這種情況:

type FilterOptional<T> = Pick<
  T,
  Exclude<
    {
      [K in keyof T]: T extends Record<K, T[K]> ? K : never;
    }[keyof T],
    undefined
  >
>;

type FilterNotOptional<T> = Pick<
  T,
  Exclude<
    {
      [K in keyof T]: T extends Record<K, T[K]> ? never : K;
    }[keyof T],
    undefined
  >
>;

type PartialEither<T, K extends keyof any> = { [P in Exclude<keyof FilterOptional<T>, K>]-?: T[P] } &
  { [P in Exclude<keyof FilterNotOptional<T>, K>]?: T[P] } &
  { [P in Extract<keyof T, K>]?: undefined };

type Object = {
  [name: string]: any;
};

export type EitherOr<O extends Object, L extends string, R extends string> = 
  (
    PartialEither<Pick<O, L | R>, L> | 
    PartialEither<Pick<O, L | R>, R>
  )  & Omit<O, L | R>;

使用例子:


// a、b二選一,并且必須傳遞一個(gè)
type RequireOne = EitherOr<
  {
    a: number;
    b: string;
  },
  'a',
  'b'
>;

// a、b二選一,或者都不傳
type RequireOneOrEmpty = EitherOr<
  {
    a?: number;
    b?: string;
  },
  'a',
  'b'
>;

實(shí)際應(yīng)用:

interface IColumn {
  title: string;
  dataIndex: string;
  render: () => React.ReactNode;
}
// 熟悉 antd 的同學(xué)應(yīng)該都知道,如果傳遞了 render 的話,其他 dataIndex 其實(shí)就沒(méi)意義
// 換個(gè)角度來(lái)說(shuō),其實(shí)它們兩個(gè)是“二選一”的屬性
interface ITableProps {
  columns: Array<
    EitherOr<
      IColumn,
      'dataIndex',
      'render'
    >
  >;
}
function Table(props: ITableProps){
  // TODO
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容