Zod v4.2.0に実装されたz.fromJSONSchema()を試す
本日2025/12/15にリリースされたZod v4.2.0でz.fromJSONSchema()が実装されました。
SchemaからJSON Schemaを生成できるtoJSONSchemaはZod v4やValibotで既にありましたが、逆のことをやるfromJSONSchemaは今までサードパーティパッケージを使わなければ実現できなかったことなので、実装された記念に試してみましょう。
今回はDenoとJSRでサクッっとやります。
JSON Schemaもjsr.jsonのものを使います。
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を読み込ませてみましたが、エラーが発生しました。
External $ref is not supported, only local refs (#/...) are allowed
どうやら"$ref": "lint-tags.v1.json"や"$ref": "lint-rules.v1.json"といった外部ファイルを参照するケースは今のところサポートしていないようです。
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