🍔

Zod v4.2.0に実装されたz.fromJSONSchema()を試す

に公開

本日2025/12/15にリリースされたZod v4.2.0でz.fromJSONSchema()が実装されました。

https://github.com/colinhacks/zod/releases/tag/v4.2.0

SchemaからJSON Schemaを生成できるtoJSONSchemaはZod v4やValibotで既にありましたが、逆のことをやるfromJSONSchemaは今までサードパーティパッケージを使わなければ実現できなかったことなので、実装された記念に試してみましょう。

https://github.com/StefanTerdell/json-schema-to-zod

今回はDenoとJSRでサクッっとやります。
JSON Schemaもjsr.jsonのものを使います。

main.ts
import * as z from "jsr:@zod/zod";

const url = "https://jsr.io/schema/config-file.v1.json";
const response = await fetch(url);
const jsonSchema = await response.json();

const schema = z.fromJSONSchema(jsonSchema);
const jsrJson = { name: "@luca/flag", exports: "./mod.ts" };

const result = schema.safeParse(jsrJson);
if (!result.success) {
  console.error(result.error.message);
} else {
  console.log(result.data);
}

早速動かしてみましょう。

deno -N main.ts
{ name: "@luca/flag", exports: "./mod.ts" }

うまくいきました。
ではjsr.jsonのキーを減らしてみるとどうでしょうか。

-const jsrJson = { name: "@luca/flag", exports: "./mod.ts" };
+const jsrJson = { exports: "./mod.ts" };
deno -N main.ts
[
  {
    "expected": "string",
    "code": "invalid_type",
    "path": [
      "name"
    ],
    "message": "Invalid input: expected string, received undefined"
  }
]

requiredなnameキーがないのでちゃんとエラーが発生するようになりました。
ではjsr.jsonのキーを元に戻して、exports値の相対パスの書き方を変えてみるとどうでしょうか。

-const jsrJson = { name: "@luca/flag" };
+const jsrJson = { name: "@luca/flag", exports: "mod.ts" };
deno -N main.ts
[
  {
    "code": "invalid_union",
    "errors": [
      [
        {
          "origin": "string",
          "code": "invalid_format",
          "format": "regex",
          "pattern": "/^\\.\\/.*$/",
          "path": [],
          "message": "Invalid string: must match pattern /^\\.\\/.*$/"
        }
      ],
      [
        {
          "expected": "record",
          "code": "invalid_type",
          "path": [],
          "message": "Invalid input: expected record, received string"
        }
      ]
    ],
    "path": [
      "exports"
    ],
    "message": "Invalid input"
  }
]

exports値が正規表現にマッチしないのでちゃんとエラーが発生しますね。
しっかりとJSON Schemaのバリデーションが行われていることが分かります。

ただいくつか制限があるので注意が必要です。
当初は下記deno.jsonのJSON Schemaを読み込ませてみましたが、エラーが発生しました。

https://github.com/denoland/deno/blob/v2.6.0/cli/schemas/config-file.v1.json#L524-L555

External $ref is not supported, only local refs (#/...) are allowed

どうやら"$ref": "lint-tags.v1.json"や"$ref": "lint-rules.v1.json"といった外部ファイルを参照するケースは今のところサポートしていないようです。

https://zod.dev/json-schema

Experimental — The z.fromJSONSchema() function is experimental and is not considered part of Zod's stable API. It is likely to undergo implementation changes in future releases.

Discussion