Skip to content

如何定义 Schema

如果消息管理一样,你要想数据支持 typesafe 那么就必须要定义它的类型。为了让他能自动填充缺失字段,我们还需要编写一个 JSON shcema 的描述文件(大部分由 chatGPT 完成)

定义一个 schema

假设我们现在需要一个 key 来存放当前登录用户的信息假设为 user,它包含俩字段 name:stirngage:number

建立 schema 文件

我们在 /src/schema 文件夹下面新建 user.ts 文件,内容如下

typescript
//  user.ts
import { JSONSchemaType } from "@webextkits/storage-local";

export type UserSchemaType = {
  name: string;
  age: number;
};

export const UserSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: {
      type: "string",
      default: "default name",
    },
    age: {
      type: "number",
      default: 18,
    },
  },
  default: {},
  required: ["name", "age"],
};
//  user.ts
import { JSONSchemaType } from "@webextkits/storage-local";

export type UserSchemaType = {
  name: string;
  age: number;
};

export const UserSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: {
      type: "string",
      default: "default name",
    },
    age: {
      type: "number",
      default: 18,
    },
  },
  default: {},
  required: ["name", "age"],
};

尽量保持命名统一

比如在 user.ts 文件中,应该导出的两个命名为 UserSchemaTypeUserSchema

UserSchemaType

UserSchemaType 用于描述这个 user 的 JSON 格式,它主要用于在操作 storage 时的 typescript 提示和检测

UserSchema

UserSchema 用于自动填充数据库中缺失字段,这是一个 JSON Schema 的结构(当前最流行的结构描述文件),这个的生成你可以直接问 chatGPT,比如我是这样问的

text
我:请按照下面这个 type 生成对应的 ajv 格式
export type UserSchemaType = {
  name: string;
  age: number;
};
我:请按照下面这个 type 生成对应的 ajv 格式
export type UserSchemaType = {
  name: string;
  age: number;
};

chatGPT 回答说

typescript
import Ajv, { JSONSchemaType } from "ajv";

// 定义UserSchemaType的ajv格式
const userSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "number" },
  },
  required: ["name", "age"],
};

// 创建一个新的ajv实例
const ajv = new Ajv();

// 编译UserSchemaType的ajv格式
const validate = ajv.compile(userSchema);

export { validate };
import Ajv, { JSONSchemaType } from "ajv";

// 定义UserSchemaType的ajv格式
const userSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "number" },
  },
  required: ["name", "age"],
};

// 创建一个新的ajv实例
const ajv = new Ajv();

// 编译UserSchemaType的ajv格式
const validate = ajv.compile(userSchema);

export { validate };

我们只需要将

typescript
const userSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "number" },
  },
  required: ["name", "age"],
};
const userSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "number" },
  },
  required: ["name", "age"],
};

复制粘贴过来即可

注意事项

为了保证 schema 能正确自动补齐缺失字段,我们应该给添加默认的 default

typescript
export const UserSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: {
      type: "string",
      //  添加默认值
      default: "default name",
    },
    age: {
      type: "number",
      //  添加默认值
      default: 18,
    },
  },
  //  添加默认值
  default: {},
  required: ["name", "age"],
};
export const UserSchema: JSONSchemaType<UserSchemaType> = {
  type: "object",
  properties: {
    name: {
      type: "string",
      //  添加默认值
      default: "default name",
    },
    age: {
      type: "number",
      //  添加默认值
      default: 18,
    },
  },
  //  添加默认值
  default: {},
  required: ["name", "age"],
};

WARNING

为了保证 storageLocal 能按预期运行,请保证每个 schema 文件都导出一个 type 和 对应的 JSON Schema 描述对象

注册 schema

我们回到 src/schema/index.ts 文件中,对刚刚定义的 schema user 进行注册导出

typescript
import { UserSchemaType, UserSchema } from "./user";

export type SchemaType = {
  user: UserSchemaType;
};

export const schema = {
  user: UserSchema,
};
import { UserSchemaType, UserSchema } from "./user";

export type SchemaType = {
  user: UserSchemaType;
};

export const schema = {
  user: UserSchema,
};

WARNING

请确保 SchemaType 和 schema 中 key 的一致性

Powered by Vitepress