คุณจะเข้าใกล้การจับคู่รูปแบบใน TypeScript อย่างไร

แนวทางใดที่แนะนำให้ทำสิ่งที่คล้ายกับการจับคู่รูปแบบใน TypeScript สิ่งที่ดีที่สุดที่ฉันเคยทำมาคือการให้ "tag" -value ที่ไม่ซ้ำกันสำหรับแต่ละอินเทอร์เฟซที่ tuple และทำ switch/case -statement ตามนั้น

interface First { tag: 'one' }
interface Second { tag: 'two' }
type Third = First | Second

function match<T>(input: Third): T {
 switch( input.tag ){
   case 'one': {
   ...
   } 
   case 'two': {
   ...
   }
   default: {
   ...
   }
 }
}

ในความคิดของฉัน นี่ยังเป็นวิธีที่ไม่เป็นมิตรและไม่เกิดผลในการทำเช่นนี้

ฉันไม่แน่ใจตัวเองว่าคุณจะผลักดันสิ่งนี้ได้ไกลแค่ไหนเนื่องจาก TypeScript ไม่ใช่การพิมพ์ระดับเฟิร์สคลาส แต่ฉันอยากลองดู


person Jimi Pajala    schedule 06.05.2018    source แหล่งที่มา
comment
ฉันรู้ว่านี่ดูเหมือนเป็นการรบกวนภาษา แต่จริงๆ แล้วมันก็ไม่ใช่เรื่องใหญ่ และอาจเป็นสิ่งที่ดีด้วยซ้ำ .. นอกจากนี้ บางคนอาจพยายามแนะนำให้ใช้คลาสและ instanceof แต่นั่นจะไม่ใช่ความคิดที่ดี -- instanceof เป็นอุปสรรคต่อการจัดหา mocks ที่ดีสำหรับการทดสอบ -- interfaces แทนที่จะเป็น instanceof คือจุดแข็งของ typescript   -  person ChaseMoskal    schedule 06.05.2018


คำตอบ (1)


อาจใช้ enum สำหรับสิ่งนี้

enum Tag {
  One,
  Two,
  Three
}

interface Taggable {
  tag: Tag
}

interface Alpha extends Taggable {
  tag: Tag.One
  a: number
}

interface Bravo extends Taggable {
  tag: Tag.Two
  b: number
}

function match<gTaggable extends Taggable = Taggable>(
  taggable: gTaggable
): gTaggable {
  switch(taggable.tag) {

    case Tag.One: {
      const {tag, a} = taggable
      // ...
      break
    }

    case Tag.Two: {
      const {tag, b} = taggable
      // ...
      break
    }

    default: {
      throw new Error(`unknown taggable "${taggable.tag}"`)
    }
  }
}

หากคุณรู้สึกซุกซนเป็นพิเศษ คุณสามารถดูการใช้สัญลักษณ์แทนการแจงนับสำหรับเนื้อหาประเภทนี้ได้

person ChaseMoskal    schedule 06.05.2018