扩展元组并应用可选属性。

huangapple go评论66阅读模式
英文:

Spreading tuples and also applying optional attributes

问题

以下是修改后的代码:

type ArrayBuilder<
  T extends Def[],
  A extends any[] = [],
  B extends any[] = [],
  C extends any[] = [],
  State extends 'A' | 'B' = 'A',
> = T extends [
  infer H extends Def,
  ...infer R extends Def[],
] ? State extends 'A' ? H['spread'] extends true ? ArrayBuilder<R, A, H['optional'] extends true ? [boolean] : [], [...A, H['type']], 'B'> : ArrayBuilder<R, [...A, H['type']], [], [], 'A'>
  : ArrayBuilder<R, A, H['optional'] extends true ? [boolean] : [], [...C, H['type']], 'B'>
  : [...A, ...B, ...C]

type Test2 = ArrayBuilder<[A, B, C]> // [string, boolean?, ...string[]]

通过在适当的位置添加条件来检查 optional 字段,我们可以实现 Test2 产生 [string, boolean?, ...string[]] 的结果。这里的条件检查将在需要时将 boolean 类型添加到类型数组中。

英文:

Can the code below be modified, such that Test2 produces: [string, boolean?, ...string[]] by factoring in the optional field?

type Def = { type: any, spread: boolean, optional: boolean }
type A = { type: string,   spread: false, optional: false }
type B = { type: boolean,  spread: false, optional: true  }
type C = { type: string[], spread: true,  optional: false }
type D = { type: number,   spread: false, optional: false }

type ArrayBuilder&lt;
  T extends Def[],
  A extends any[] = [],
  B extends any[] = [],
  C extends any[] = [],
  State extends &#39;A&#39; | &#39;B&#39; = &#39;A&#39;,
&gt; = T extends [
  infer H extends Def,
  ...infer R extends Def[],
] ? State extends &#39;A&#39; ? H[&#39;spread&#39;] extends true ? ArrayBuilder&lt;R, A, H[&#39;type&#39;], [], &#39;B&#39;&gt; : ArrayBuilder&lt;R, [...A, H[&#39;type&#39;]], [], [], &#39;A&#39;&gt;
  :ArrayBuilder&lt;R, A, B, [...C, H[&#39;type&#39;]], &#39;B&#39;&gt;
  : [...A, ...B, ...C]

type Test1 = ArrayBuilder&lt;[A,C,D]&gt; // [string, ...string[], number]

// Can the code above be modified, such that Test2 produces: [string, boolean?, ...string[]] by factoring in the optional field?
type Test2 = ArrayBuilder&lt;[A,B,C]&gt; // [string, boolean, ...string[]] - should become [string, boolean?, ...string[]]

To apply the spread, I'm doing [...A,...ItemToSpread], but to apply the optional attribute I must do {[I in keyof T]?: T[I] } - which doesn't play nice with spreads.

code

答案1

得分: 2

正如你检查H[&quot;spread&quot;]一样,你可以在将H[&quot;type&quot;]传递给ArrayBuilder之前检查H[&quot;optional&quot;]

type ArrayBuilder&lt;
  T extends Def[],
  A extends any[] = [],
  B extends any[] = [],
  C extends any[] = [],
  State extends &quot;A&quot; | &quot;B&quot; = &quot;A&quot;
&gt; = T extends [infer H extends Def, ...infer R extends Def[]]
  ? State extends &quot;A&quot;
    ? H[&quot;spread&quot;] extends true
      ? ArrayBuilder&lt;R, A, H[&quot;type&quot;], [], &quot;B&quot;&gt;
      : H[&quot;optional&quot;] extends true ? ArrayBuilder&lt;R, [...A, H[&quot;type&quot;]?], [], [], &quot;A&quot;&gt; : ArrayBuilder&lt;R, [...A, H[&quot;type&quot;]], [], [], &quot;A&quot;&gt;
    : H[&quot;optional&quot;] extends true ? ArrayBuilder&lt;R, A, B, [...C, H[&quot;type&quot;]?], &quot;B&quot;&gt; : ArrayBuilder&lt;R, A, B, [...C, H[&quot;type&quot;]], &quot;B&quot;&gt;
  : [...A, ...B, ...C];

如果你启用了exactOptionalPropertyTypes,你将获得Test2的期望结果:

type Test2 = ArrayBuilder&lt;[A, B, C]&gt;; // [string, boolean?, ...string[]]

Playground

英文:

Just as you check for H[&quot;spread&quot;], you can check for H[&quot;optional&quot;] before passing H[&quot;type&quot;] to ArrayBuilder:

type ArrayBuilder&lt;
  T extends Def[],
  A extends any[] = [],
  B extends any[] = [],
  C extends any[] = [],
  State extends &quot;A&quot; | &quot;B&quot; = &quot;A&quot;
&gt; = T extends [infer H extends Def, ...infer R extends Def[]]
  ? State extends &quot;A&quot;
    ? H[&quot;spread&quot;] extends true
      ? ArrayBuilder&lt;R, A, H[&quot;type&quot;], [], &quot;B&quot;&gt;
      : H[&quot;optional&quot;] extends true ? ArrayBuilder&lt;R, [...A, H[&quot;type&quot;]?], [], [], &quot;A&quot;&gt; : ArrayBuilder&lt;R, [...A, H[&quot;type&quot;]], [], [], &quot;A&quot;&gt;
    : H[&quot;optional&quot;] extends true ? ArrayBuilder&lt;R, A, B, [...C, H[&quot;type&quot;]?], &quot;B&quot;&gt; : ArrayBuilder&lt;R, A, B, [...C, H[&quot;type&quot;]], &quot;B&quot;&gt;
  : [...A, ...B, ...C];

and if you have exactOptionalPropertyTypes enabled, you will get the desired result for Test2:

type Test2 = ArrayBuilder&lt;[A, B, C]&gt;; // [string, boolean?, ...string[]]

Playground

huangapple
  • 本文由 发表于 2023年2月27日 07:37:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定