Zod 能够解析 JSON 文件的内容吗?

bai*_*idz 2 zod

这可能与Zod: Parse external JSON file重复


我有一个函数需要一个 JSON 字符串并将其解析为由 Zod 模式推断的给定类型

const createConfigurationFromJson = (content: string): Configuration => {
  const rawConfiguration = JSON.parse(content);

  return configurationSchema.parse(rawConfiguration);
};
Run Code Online (Sandbox Code Playgroud)

如果 JSON 内容是无效 JSON 或 Zod 抛出解析错误,则此函数可能会抛出异常。在不使用其他第三方库的情况下,是否可以让Zod解析JSON字符串?所以我可以确定只能是Zod错误?

Sam*_*jig 6

如果您希望它完全在 zod 中,那么创建一个自定义模式true,如果它是有效的 json,则返回,否则返回false。然后,在将其发送到 之前configurationSchema,您需要将字符串转换content为对象。您可以使用.pipe将其传递给configurationSchema.

const configurationSchema = z.object({
  name: z.string(),
  version: z.string(),
  description: z.string(),
});

type Configuration = z.infer<typeof configurationSchema>;

const createConfigurationFromJson = (content: string): Configuration => {
  return z
    .custom<string>((data) => {
      try {
        JSON.parse(content);
      } catch (error) {
        return false;
      }
      return true;
    }, "invalid json") // write whatever error you want here
    .transform((content) => JSON.parse(content))
    .pipe(configurationSchema)
    .parse(content);
};
Run Code Online (Sandbox Code Playgroud)

(您可以对其进行优化以使用第一个的存储值JSON.parse,但这只是一个过早的优化,不会影响绝大多数项目)

当测试时

const configuration1 = createConfigurationFromJson(`{
  "name": "my-app",
  "version": "1.0.0",
  "description": "My awesome app"
}`);

const configuration2 = createConfigurationFromJson(`{
  "banana": ""
}`);

const configuration3 = createConfigurationFromJson(`{
  fiadsjfoiajsdoivjdaoij
`);
Run Code Online (Sandbox Code Playgroud)

它将成功和错误输出为

configuration1 {
  name: "my-app",
  version: "1.0.0",
  description: "My awesome app"
}
configuration2 159 |     const json = JSON.stringify(obj, null, 2);
160 |     return json.replace(/"([^"]+)":/g, "$1:");
161 | };
162 | class ZodError extends Error {
163 |     constructor(issues) {
164 |         super();
            ^
ZodError: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "name"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "version"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "description"
    ],
    "message": "Required"
  }
]
 errors: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "name"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "version"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "description"
    ],
    "message": "Required"
  }
]

      at new ZodError (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:164:8)
      at /Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:537:30
      at parse (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:636:14)
      at /Users/sgunter/code/zod-parse-json/index.ts:46:25

configuration3 159 |     const json = JSON.stringify(obj, null, 2);
160 |     return json.replace(/"([^"]+)":/g, "$1:");
161 | };
162 | class ZodError extends Error {
163 |     constructor(issues) {
164 |         super();
            ^
ZodError: [
  {
    "code": "custom",
    "message": "invalid json",
    "fatal": true,
    "path": []
  }
]
 errors: [
  {
    "code": "custom",
    "message": "invalid json",
    "fatal": true,
    "path": []
  }
]

      at new ZodError (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:164:8)
      at /Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:537:30
      at parse (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:636:14)
      at /Users/sgunter/code/zod-parse-json/index.ts:55:25
Run Code Online (Sandbox Code Playgroud)