创建一个具有一些动态键和一些静态键的架构,使用zod。

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

Create a schema that has some dynamic keys and some static keys with zod

问题

我想要实现类似这种类型的结果,但使用zod。

type a = {
  [key: string]: string;
  name: string;
  surname: string;
}

因此,这是一个具有一些静态字段但接受其他动态字段的类型。

我知道 z.record(z.string(), z.string()),但似乎它只能重新创建类型只有动态键的情况,如:

type zod = {
  [key: string]: string;
}

我还尝试使用 merge:

const dynamicPropertiesSchema = z.record(z.string());

export const PersonSchema = z.object({
  anagraphics: z.object({
    name: z.string(),
    surname: z.string(),
  }).merge(dynamicPropertiesSchema),
  notes: z.array(z.string()),
});

但我收到以下错误,强调了 .merge() 参数:

“类型参数 'ZodRecord <ZodString, ZodString>' 无法分配给类型参数 'AnyZodObject'。 类型 'ZodRecord <ZodString, ZodString>' 缺少类型 'ZodObject <any, any, any, { [x: string]: any; }, { [x: string]: any; }>' 的以下属性:_cached,_getCached,shape,strict,以及其他14个.ts(2345)”

总之,我想要类似这样的东西:

const mixedSchema = z.object({
  z.record(z.string(), z.string()),
  name: z.string(),
  surname: z.string(),
});

是否有办法实现这个?
感谢您的帮助!

英文:

I want to achieve a result similar to this type, but using zod.

type a = {
  [key: string]: string;
  name: string;
  surname: string;
}

So a type that has some static fields but accepts other dynamic ones.

I know about z.record(z.string(), z.string()), but it seems like it can only recreate the case where the type only has dynamic keys, as in:

type zod = {
  [key: string]: string;
}

I also tried using merge:

const dynamicPropertiesSchema = z.record(z.string());

export const PersonSchema = z.object({
  anagraphics: z.object({
    name: z.string(),
    surname: z.string(),
  }).merge(dynamicPropertiesSchema),
  notes: z.array(z.string()),
});

But I get the following error highlighting the .merge() parameter:

Argument of type &#39;ZodRecord&lt;ZodString, ZodString&gt;&#39; is not assignable to parameter of type &#39;AnyZodObject&#39;. Type &#39;ZodRecord&lt;ZodString, ZodString&gt;&#39; is missing the following properties from type &#39;ZodObject&lt;any, any, any, { [x: string]: any; }, { [x: string]: any; }&gt;&#39;: _cached, _getCached, shape, strict, and 14 more.ts(2345)

So, all in all, I'd like something like this:

const mixedSchema = z.object({
  z.record(z.string(), z.string()),
  name: z.string(),
  surname: z.string(),
});
 

Would this be able to be achieved somehow?
Thanks for your help!

答案1

得分: 3

我认为实现这个的正确方式是使用交集:

```ts
const schema = z.intersection(z.object({
    name: z.string(),
    surname: z.string(),    
}), z.record(z.string(), z.string()));

type T = z.infer<typeof schema>;
//   ^? { name: string; surname: string } & Record<string, string>

类似于在普通的TS类型中使用的方式:

type T = { name: string; surname: string } & Record<string, string>;

Playground


<details>
<summary>英文:</summary>

I believe the correct way to accomplish this would be to use an intersection:

```ts
const schema = z.intersection(z.object({
    name: z.string(),
    surname: z.string(),    
}), z.record(z.string(), z.string()));

type T = z.infer&lt;typeof schema&gt;;
//   ^? { name: string; surname: string } &amp; Record&lt;string, string&gt;

Similar to how you would do it with plain TS types:

type T = { name: string; surname: string } &amp; Record&lt;string, string&gt;;

Playground

huangapple
  • 本文由 发表于 2023年2月23日 22:59:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75546547.html
匿名

发表评论

匿名网友

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

确定