typescript類型編程記錄:實(shí)現(xiàn)一個(gè)含有聯(lián)合類型的類型組合

需求示例:

一個(gè)HTTP請(qǐng)求參數(shù)類型,用于創(chuàng)建會(huì)議。
會(huì)議可以為音頻、或者視頻,所以參數(shù)類型要么為音頻會(huì)議的類型、要么為視頻會(huì)議的類型,剩下的是兩種會(huì)議共有的參數(shù)。

開始的想法:

interface VideoConferenceRoom {
    mode: "VIDEO";
    layout: 1 | 2 | 3 | 4 | 6 | 9;
    bitrate: number;
    framerate: number;
    resolution: "CIF" | "QCIF" | "VGA" | "SVGA" | "XVGA" | "HD720" | "QVGA";
}

interface AudioConferenceRoom {
    mode: "AUDIO";
}

interface CreateConferenceRoomParams 
    extends VideoConferenceRoom,
    AudioConferenceRoom {
    extension_number: string;
    room_pin: string;
    admin_pin: string;
    subject: string;
    language: string;
    custom_options: string;
    outbound_caller_ids: { provider_id: string; caller_id: string }[];
}
error: Interface 'CreateConferenceRoomParams' cannot simultaneously extend types 'VideoConferenceRoom' and 'AudioConferenceRoom'.
  Named property 'mode' of types 'VideoConferenceRoom' and 'AudioConferenceRoom' are not identical.

失敗,因?yàn)?code>interface的多重繼承需要被繼承的接口完全一致,而此處的兩個(gè)接口的mode字段并不兼容。

那么我們需要一個(gè)Unit types的中間類型:

......省略......

// 新增
type ConferenceRoom = AudioConferenceRoom | VideoConferenceRoom;

interface CreateConferenceRoomParams
    extends ConferenceRoom {
    extension_number: string;
    room_pin: string;
    admin_pin: string;
    subject: string;
    language: string;
    custom_options: string;
    outbound_caller_ids: { provider_id: string; caller_id: string }[];
}
error: An interface can only extend an object type or intersection of object types with statically known members.

失敗,接口只能繼承一個(gè)靜態(tài)類型,而聯(lián)合類型是不確定的。那么最后的:

interface VideoConference {
  mode: "VIDEO";
  layout: 1 | 2 | 3 | 4 | 6 | 9;
  bitrate: number;
  framerate: number;
  resolution: "CIF" | "QCIF" | "VGA" | "SVGA" | "XVGA" | "HD720" | "QVGA";
}

interface AudioConference {
  mode: "AUDIO";
}

type ConferenceMedia = VideoConference | AudioConference;

export type CreateConferenceRoomParams = ConferenceMedia & {
  extension_number: string;
  room_pin: string;
  admin_pin: string;
  subject: string;
  language: string;
  custom_options: string;
  outbound_caller_ids: { provider_id: string; caller_id: string }[];
};

使用類型別名來(lái)實(shí)現(xiàn),將兩個(gè)類型交叉后,得到一個(gè)符合需求的類型組合。
順便類型名稱改了一下,變得更符合語(yǔ)義

?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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