ค้นหาเว็บไซต์

typescript - อินเทอร์เฟซที่เทียบเท่าสำหรับประเภทยูเนียน


ฉันมีประเภท Typescript ที่กำหนดไว้ดังนี้:

export type IStepFunctionOperand =
  | IStepFunctionOperand_StringEquals
  | IStepFunctionOperand_StringGreaterThan
  | IStepFunctionOperand_StringGreaterThanEquals
  | IStepFunctionOperand_StringLessThan
  | IStepFunctionOperand_StringLessThanEquals
  | IStepFunctionOperand_NumericEquals
  | IStepFunctionOperand_NumericGreaterThan
  | IStepFunctionOperand_NumericGreaterThanEquals
  | IStepFunctionOperand_NumericLessThan
  | IStepFunctionOperand_NumericLessThanEquals;

โดยที่เงื่อนไขแต่ละข้อมีลักษณะคล้ายกับดังต่อไปนี้:

export interface IStepFunctionOperand_NumericLessThanEquals
  extends IStepFunctionBaseLogicalOperand {
  /** compare the value passed in -- and scoped by "Variable" -- to be numerically equal to a stated number */
  NumericLessThanEquals?: number;
}

export interface IStepFunctionBaseLogicalOperand {
  /** points to the specific area of context which is being evaluated in the choice */
  Variable: string;
}

นี่ทำสิ่งที่ฉันต้องการในฐานะ type แต่จะสะดวกมากถ้า type นี้สามารถถูกสร้างเป็น interface ได้ หากฉันสามารถทำเช่นนี้ได้ ฉันก็สามารถกำหนด interface ได้ดังนี้:

export interface IStepFunctionChoiceItem<T> extends Partial<IStepFunctionOperand> {
  // simple operands leverage inheritance but are optional

  // complex operators
  And?: IStepFunctionOperand[];
  Or?: IStepFunctionOperand[];
  Not?: IStepFunctionOperand;

  // State machine
  Next?: keyof T;
  End?: true;
}

นี่เป็นไปได้หรือไม่?

คำตอบ #1

แม้ว่าคุณจะไม่สามารถใช้ interface เพื่อแทน union ได้ เช่น เพื่อสืบทอดจากมัน แต่คุณสามารถใช้ intersection types กับ type aliases เพื่อใช้ซ้ำหรือกำหนดพารามิเตอร์ให้กับ union type

จากตัวอย่างของคุณ:

export type StepFunctionChoiceItem<T> =
  & Partial<StepFunctionOperand>
  & {
  // simple operands leverage inheritance but are optional

  // complex operators
  and?: StepFunctionOperand[];
  or?: StepFunctionOperand[];
  not?: StepFunctionOperand;

  // State machine
  next?: keyof T;
  end?: true;
};

export type StepFunctionOperand =
  | StepFunctionOperand_StringEquals
  | StepFunctionOperand_StringGreaterThan
  | StepFunctionOperand_StringGreaterThanEquals
  | StepFunctionOperand_StringLessThan
  | StepFunctionOperand_StringLessThanEquals
  | StepFunctionOperand_NumericEquals
  | StepFunctionOperand_NumericGreaterThan
  | StepFunctionOperand_NumericGreaterThanEquals
  | StepFunctionOperand_NumericLessThan
  | StepFunctionOperand_NumericLessThanEquals;

นี่ไม่เหมือนกับการขยายอินเทอร์เฟซเพราะว่า ในบรรดาความแตกต่างอื่น ๆ สมาชิกที่มีชื่อเดียวกันจะไม่ได้ถูกแทนที่หรือถูกโอเวอร์โหลด แต่จะถูกตัดกันแทน อย่างไรก็ตาม ประเภทการตัดกันจะให้พฤติกรรมที่ต้องการโดยพื้นฐาน