如何在TypeScript中用AJV的JSONSchemaType定义unknown类型的JSON Schema
使用AJV的JSONSchemaType创建与TypeScript接口对应的JSON Schema时,因接口包含unknown类型属性,赋值时TypeScript抛出类型不兼容错误。
TypeScript接口及两次Schema尝试代码如下:
import { JSONSchemaType } from "ajv"; interface OptionArray { options?: { title?: string; value: unknown; }[]; } const schemaAttempt1: JSONSchemaType<OptionArray> = { type: "object", properties: { options: { type: "array", items: { type: "object", properties: { title: { type: "string", nullable: true }, value: {} }, required: ["value"], additionalProperties: false }, nullable: true } }, required: [], additionalProperties: false }; const schemaAttempt2: JSONSchemaType<OptionArray> = { type: "object", properties: { options: { type: "array", items: { type: "object", properties: { title: { type: "string", nullable: true }, value: true }, required: ["value"], additionalProperties: false }, nullable: true } }, required: [], additionalProperties: false };
第一次尝试触发的TypeScript错误:
The types of 'properties.value' are incompatible between these types.
Type '{}' is not assignable to type '{ $ref: string; } | (UncheckedJSONSchemaType<unknown, false> & { nullable: true; const?: null | undefined; enum?: readonly unknown[] | undefined; default?: unknown; })'.
第二次尝试的错误:
The types of 'properties.value' are incompatible between these types.
Type 'boolean' is not assignable to type '{ $ref: string; } | (UncheckedJSONSchemaType<unknown, false> & { nullable: true; const?: null | undefined; enum?: readonly unknown[] | undefined; default?: unknown; })'.
需解决:如何在TypeScript中使用AJV的JSONSchemaType正确定义包含unknown类型属性的JSON Schema?
TypeScript的unknown类型对应JSON中任意合法值,JSON Schema没有直接的单一关键字匹配,需显式声明属性支持所有JSON基础类型,具体有两种可行方式:
方式1:枚举所有JSON基础类型
JSON的合法类型包括string、number、integer、boolean、object、array和null,将这些类型放入type数组中,即可匹配任意JSON值,同时通过TypeScript类型检查:
const schema: JSONSchemaType<OptionArray> = { type: "object", properties: { options: { type: "array", items: { type: "object", properties: { title: { type: "string", nullable: true }, value: { type: ["string", "number", "integer", "boolean", "object", "array", "null"] } }, required: ["value"], additionalProperties: false }, nullable: true } }, required: [], additionalProperties: false };
方式2:使用类型断言简化(适合快速场景)
若不想枚举所有类型,可通过类型断言跳过TypeScript的严格检查,同时保证AJV的运行时逻辑正确:
const schema: JSONSchemaType<OptionArray> = { type: "object", properties: { options: { type: "array", items: { type: "object", properties: { title: { type: "string", nullable: true }, value: {} as const }, required: ["value"], additionalProperties: false }, nullable: true } }, required: [], additionalProperties: false };
注意:类型断言会绕过TypeScript的类型检查,仅在确认
{}符合AJV的"任意值"匹配逻辑时使用。
内容的提问来源于stack exchange,提问作者mi105

