ใช้ประเภทสหภาพกับทั่วไป

Oct 27 2020

ฉันมีฟังก์ชันที่รับพารามิเตอร์ซึ่งเป็นอ็อบเจ็กต์ที่ประกอบด้วยฟิลด์ (สตริง) และอาร์กิวเมนต์ (อ็อบเจ็กต์ลิเทอรัล)

ฉันต้องการให้การตรวจสอบประเภทอาร์กิวเมนต์ได้รับการตรวจสอบความถูกต้องโดยขึ้นอยู่กับฟิลด์นั้นคืออะไร ฉันต้องการสร้างคำจำกัดความที่สามารถขยายได้ทุกที่ที่ฉันต้องการ (ดังนั้นจึงเป็นเรื่องทั่วไป)

คำจำกัดความ:

 export interface EventDefinition<
    TField extends string,
    TArgs extends any
  > {
    field: TField
    arguments: TArgs
  }

หน้าที่ของฉัน:


export const myFn =  (
  params:
    | EventDefinition<
        'actionOne',
        {
          id: string
        }
      >
    | EventDefinition<
        'actionTwo',
        {
          emailAddress: string
        }
      >
) => {
  const { args, field } = params

  switch(field) {
    case 'actionOne':
      console.log(args.id)
      break;
      case 'actionTwo':
      console.log(args.emailAddress)
      break;
  }
}

ในขณะที่คุณสมบัติฟิลด์ตรวจสอบ args do not และส่งผลให้เกิดข้อผิดพลาด (สำหรับ ex กับ args.id):

Property 'id' does not exist on type '{ id: string }'.
Property 'id' does not exist on type '{ emailAddress: string; }'.

ฉันจะกำหนดสิ่งนี้ให้ถูกต้องได้อย่างไร?

คำตอบ

3 TitianCernicova-Dragomir Oct 27 2020 at 03:38

typescript จะไม่ป้องกันตัวแปรหนึ่งโดยอิงจากตัวแปรอื่นซึ่งไม่ได้รับการสนับสนุน

หากคุณใช้อาร์กิวเมนต์เองการวิเคราะห์โฟลว์การควบคุมสามารถกำหนดประเภทได้อย่างเหมาะสม

  switch(params.field) {
    case 'actionOne':
      console.log(params.arguments.id)
      break;
      case 'actionTwo':
      console.log(params.arguments.emailAddress)
      break;
  }

ลิงค์สนามเด็กเล่น