Dapatkah Antarmuka Skrip Ketik mengungkapkan kendala kemunculan bersama untuk properti
Apakah ada pola standar dalam Antarmuka Skrip Jenis monolitik atau definisi Jenis untuk menegaskan properti muncul bersamaan atau tidak muncul sama sekali?
Misalnya suatu item bisa valid jika terlihat seperti ini ...
{
id:"ljklkj",
spellcheck:true,
spellcheckModel:"byzantine",
}
...atau ini...
{
id:"ljklkj",
}
Namun itu akan menjadi tidak valid jika salah satu dari properti pemeriksa ejaan terjadi secara terpisah.
{
id:"ljklkj",
spellcheckModel:"byzantine",
}
{
id:"ljklkj",
spellcheck:true,
}
Monolitis
Tentu saja kasus sederhana di atas dapat diselesaikan dengan membuat Data dan Jenis atau Antarmuka SpellcheckData. Dalam kasus aplikasi saya, bagaimanapun, akan ada lebih dari satu 'cluster' properti yang terjadi bersamaan. Mendefinisikan tipe baru untuk setiap kombinasi kejadian bersama akan menyebabkan ledakan tipe untuk mengungkapkan kasusnya.
Untuk alasan ini saya menyebut solusi sebagai antarmuka 'monolitik'. Tentu saja mungkin perlu menggunakan beberapa bentuk komposisi untuk mendefinisikannya.
Apa yang Saya Coba
Saya telah mencoba untuk menemukan contoh seperti ini dalam referensi bahasa Ketikan, tetapi tanpa mengetahui apa nama fitur itu, (atau memang jika itu adalah fitur yang dapat diekspresikan sama sekali), saya kesulitan. Properti dapat menjadi opsional secara individual tetapi saya tidak dapat melihat cara untuk mengekspresikan kejadian bersama.
Teknologi Terkait
Fitur yang setara untuk validasi data XML dibahas di sini ... https://www.w3.org/wiki/Co-occurrence_constraints
Untuk JSON, saya memahami bahasa skema seperti Schematron dan Aturan Konten Json dapat mengekspresikan batasan bersama.
Contoh yang berhasil
Jika saya membayangkan sintaks skrip ketikan untuk kasus kendala bersama yang diterapkan pada set parameter HTTP untuk mesin pencari Solr, mungkin akan terlihat seperti ini, menunjukkan bahwa Anda dapat memilih untuk sepenuhnya memenuhi parameter Ejaan atau Grup, atau tidak sama sekali - serikat pekerja di mana setiap jenis adalah opsional (ditunjukkan dengan ? ) ...
type SolrPassthru =
SolrCoreParams & (
SolrSpellParams? |
SolrGroupParams?
)
Ini kontras dengan contoh di bawah ini, yang saya yakini adalah Skrip Ketik yang benar, tetapi memerlukan SEMUA parameter dari setiap kelompok parameter.
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
Jawaban
Silakan coba berikut ini. Tampaknya ini menunjukkan kesalahan di tempat yang benar.
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: ""};
Tautan taman bermain
Memperbarui
Jika Anda lebih suka meneruskan tipe sebagai tupel, Anda dapat menggunakan utilitas berikut:
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]>
Jika beberapa properti diperlukan:
type Monolith = Data & CombinationOf<[Data, SpellCheckData, MoreData]>