สามารถ typescript อินเทอร์เฟซแสดงข้อ จำกัด การเกิดร่วมสำหรับคุณสมบัติ

Aug 17 2020

มีรูปแบบมาตรฐานภายในอินเทอร์เฟซแบบเสาหินหรือนิยามประเภทเพื่อยืนยันคุณสมบัติที่ปรากฏร่วมกันหรือไม่ปรากฏเลย

ตัวอย่างเช่นรายการสามารถใช้ได้หากมีลักษณะเช่นนี้ ...

{
  id:"ljklkj",
  spellcheck:true,
  spellcheckModel:"byzantine",
}

... หรือนี่ ...

{
  id:"ljklkj",
}

อย่างไรก็ตามจะไม่ถูกต้องหากคุณสมบัติการตรวจการสะกดอย่างใดอย่างหนึ่งเกิดขึ้นอย่างแยกจากกัน

{
  id:"ljklkj",
  spellcheckModel:"byzantine",
}
{
  id:"ljklkj",
  spellcheck:true,
}

เสาหิน

แน่นอนว่ากรณีง่ายๆข้างต้นสามารถแก้ไขได้โดยการสร้างข้อมูลและ SpellcheckData Type หรือ Interface อย่างไรก็ตามในกรณีแอปพลิเคชันของฉันจะมีคุณสมบัติ 'คลัสเตอร์' ที่เกิดร่วมกันมากกว่าหนึ่งรายการ การกำหนดประเภทใหม่สำหรับการรวมกันทุกครั้งจะนำไปสู่การระเบิดของประเภทเพื่อแสดงกรณี

ด้วยเหตุนี้ฉันจึงเรียกโซลูชันนี้ว่าอินเทอร์เฟซ 'เสาหิน' แน่นอนว่าอาจจำเป็นต้องใช้องค์ประกอบบางรูปแบบเพื่อกำหนด

สิ่งที่ฉันพยายาม

ฉันได้พยายามค้นหาตัวอย่างเช่นนี้ในการอ้างอิงภาษา typescript แต่ไม่รู้ว่าคุณลักษณะนี้เรียกว่าอะไร (หรือแน่นอนว่าเป็นคุณลักษณะที่สามารถแสดงออกได้เลย) ฉันกำลังดิ้นรน คุณสมบัติสามารถเลือกได้ทีละรายการ แต่ฉันไม่เห็นวิธีการแสดงเหตุการณ์ร่วม

เทคโนโลยีที่เกี่ยวข้อง

คุณลักษณะที่เทียบเท่ากันสำหรับการตรวจสอบข้อมูล XML จะกล่าวถึงที่นี่ ... https://www.w3.org/wiki/Co-occurrence_constraints

สำหรับ JSON ฉันเข้าใจภาษาสคีมาเช่น Schematron และ Json Content Rules สามารถแสดงข้อ จำกัด ร่วมได้

ตัวอย่างที่ใช้งานได้

ถ้าฉันจะนึกภาพไวยากรณ์ typescript สำหรับกรณี co-constraint ที่ใช้กับชุดพารามิเตอร์ HTTP สำหรับเครื่องมือค้นหา Solr อาจมีลักษณะเช่นนี้แสดงว่าคุณสามารถเลือกที่จะตอบสนองพารามิเตอร์ Spell หรือ Group ได้อย่างสมบูรณ์หรือไม่ก็ได้ - สหภาพซึ่งแต่ละประเภทเป็นทางเลือก (ระบุโดย? ) ...

type SolrPassthru =
  SolrCoreParams & (
    SolrSpellParams? |
    SolrGroupParams?  
  )

สิ่งนี้แตกต่างกับตัวอย่างด้านล่างซึ่งฉันเชื่อว่าเป็น typescript ที่ถูกต้อง แต่ต้องการพารามิเตอร์ทั้งหมดจากพารามิเตอร์แต่ละกลุ่ม

type SolrCoreParams = {
  defType: SolrDefType,
  boost: SolrBoostType,
}

type SolrSpellParams = {
  spellcheck: "true" | "false",
  "spellcheck.collate": "true" | "false",
  "spellcheck.maxCollationTries": 1,
}

type SolrGroupParams = {
  group: "true" | "false",
  "group.limit": '4'
  "group.sort": 'group_level asc,score desc,published desc,text_sort asc'
  "group.main": 'true'
  "group.field": 'group_uri'
}

type SolrPassthru =
  SolrCoreParams & 
  SolrSpellParams &
  SolrGroupParams

คำตอบ

3 Lesiak Aug 17 2020 at 15:45

โปรดลองทำดังต่อไปนี้ ดูเหมือนว่าจะแสดงข้อผิดพลาดในตำแหน่งที่ถูกต้อง

type None<T> = {[K in keyof T]?: never}
type EitherOrBoth<T1, T2> = T1 & None<T2> | T2 & None<T1> | T1 & T2

interface Data {
  id: string;
}

interface SpellCheckData {
  spellcheck: boolean,
  spellcheckModel: string,
}

// Two interfaces
var z1: EitherOrBoth<Data, SpellCheckData> = { id: "" };
var z2: EitherOrBoth<Data, SpellCheckData> = { spellcheck: true,  spellcheckModel: 'm'};
var z3ERROR: EitherOrBoth<Data, SpellCheckData> = { spellcheck: true};
var z4: EitherOrBoth<Data, SpellCheckData> = { id: "", spellcheck: true,  spellcheckModel: 'm'};

interface MoreData {
  p1: string,
  p2: string,
  p3: string,
}

type Monolith = EitherOrBoth<Data, EitherOrBoth<SpellCheckData, MoreData>>

var x1: Monolith  = { id: "" };
var x2: Monolith  = { spellcheck: true,  spellcheckModel: 'm'};
var x3ERROR: Monolith  = { spellcheck: true};                       
var x4: Monolith  = { id: "", spellcheck: true,  spellcheckModel: 'm'};
var x5ERROR: Monolith  = { p1: ""};                                  
var x6ERROR: Monolith  = { p1: "", p2: ""};
var x7: Monolith  = { p1: "", p2: "", p3: ""};
var x8: Monolith  = { id: "", p1: "", p2: "", p3: ""};
var x9ERROR: Monolith  = { id: "", spellcheck: true, p1: "", p2: "", p3: ""};
var x10: Monolith  = { id: "", spellcheck: true, spellcheckModel: 'm', p1: "", p2: "", p3: ""};

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

อัปเดต

หากคุณต้องการส่งผ่านประเภทเป็นทูเปิลคุณสามารถใช้ยูทิลิตี้ต่อไปนี้:

type CombinationOf<T> = T extends [infer U1, infer U2] ? EitherOrBoth<U1, U2> :
                        T extends [infer U1, infer U2, infer U3] ? EitherOrBoth<U1, EitherOrBoth<U2, U3>> :
                        T extends [infer U1, infer U2, infer U3, infer U4] ? EitherOrBoth<U1, EitherOrBoth<U2, EitherOrBoth<U3, U4>>> :
                        never;

type Monolith = CombinationOf<[Data, SpellCheckData, MoreData]>

หากต้องการคุณสมบัติบางประการ:

type Monolith = Data & CombinationOf<[Data, SpellCheckData, MoreData]>