Typescript接口可以表达属性的共现约束吗 [英] Can Typescript Interfaces express co-occurrence constraints for properties

查看:67
本文介绍了Typescript接口可以表达属性的共现约束吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在整体式Typescript接口或Type定义中是否存在用于声明属性一起出现或根本不出现的标准模式?

Is there a standard pattern within a monolithic Typescript Interface or Type definitions to assert properties either appear together or don't appear at all?

例如,某项可能有效看起来像这样...

For example an item could be valid if it looked like this...

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

...或此。 ..

...or this...

{
  id:"ljklkj",
}

但是,如果其中一个拼写检查属性是孤立发生的,则它将无效。

However it would be invalid if either of the spellcheck properties occurred in isolation.

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


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

单片

当然,可以通过创建数据和SpellcheckData类型或接口来解决上述简单情况。但是,在我的应用案例中,将有多个同时出现的集群。为同时出现的每种组合定义一个新类型会导致类型爆炸,以表达这种情况。

Of course the simple case above could be resolved by creating a Data and a SpellcheckData Type or Interface. In my application case, however, there will be more than one 'cluster' of co-occurring properties. Defining a new type for every combination of co-occurrence would lead to an explosion of types in order to express the case.

因此,我将解决方案称为整体式界面。当然,可能有必要使用某种形式的组合来定义它。

For this reason I've referred to the solution as a 'monolithic' interface. Of course it may be necessary to use some form of composition to define it.

我尝试过的内容

我试图在Typescript语言参考中找到类似的示例,但是在不知道该功能可能被称为什么的情况下(或者实际上,如果它是一个可以表达的功能),我一直在努力。属性可以单独是可选的,但我看不到表达共现的方法。

I have tried to find examples like this within the Typescript language reference, but without knowing what the feature might be called, (or indeed if it's a feature that can be expressed at all), I'm struggling. Properties can be individually optional but I can't see a way of expressing co-occurrence.

相关技术

这里讨论了XML数据验证的等效功能...
https:// www .w3.org / wiki / Co-occurrence_constraints

An equivalent feature for XML data validation is discussed here... https://www.w3.org/wiki/Co-occurrence_constraints

对于JSON,我理解诸如Schematron和Json Content Rules之类的模式语言能够表达共约束。

For JSON I understand schema languages like Schematron and Json Content Rules are able to express co-constraints.

可行示例

如果我想像一下将共同约束条件的打字稿语法应用于Solr搜索引擎的HTTP参数集,它可能看起来像这样,表明您可以选择完全满足Spell或Group参数,或者根本不满足-每种类型都是可选的并集(由 )...

If I were to imagine typescript syntax for the co-constraint case applied to HTTP parameter sets for the Solr search engine, it might look like this, indicating that you could opt in to fully satisfying the Spell or Group params, or not at all - a union in which each type is optional (indicated by the ?) ...

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

这与下面的示例形成对比,我相信这是正确的Typescript,但是需要每组参数中的所有参数。

This contrasts with the example below, which is I believe is correct Typescript, but requires ALL parameters from each group of parameters.

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


推荐答案

请尝试以下操作。似乎在正确的位置显示了错误。

Please try the following. It seems it shows errors in the correct places.

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: ""};

游乐场链接

更新

如果您希望将类型作为元组传递,则可以可以使用以下实用程序:

If you prefer to pass types as a tuple, you can use the following utility:

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]>

这篇关于Typescript接口可以表达属性的共现约束吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆