ts拯救前端:優雅的在執行時校驗後端介面返回資料型別 typescript-json-schema+ ajv

Chiffon1996發表於2024-05-29

包管理器:pnpm
環境:node
依賴:typescript-json-schemaajv

準備工作

1、安裝依賴

pnpm add typescript-json-schema 
pnpm add ajv 

2、準備需要校驗的資料型別

// userType.ts
export interface User {
  id: string;
  token: string;
  nick?: string;
}

3、使用typescript-json-schema資料型別轉為可供ajv 使用的JSON Schema

// tsJsonSchema.ts 
import { User } from './userType';

// 新增指令碼
"scripts": {
    // ...
    "json": "typescript-json-schema tsJsonSchema.ts '*' -o tsJsonSchema.json --id=api --required --strictNullChecks"
}

// 執行指令碼 pnpm run json
// 生成 tsJsonSchema.json 檔案 

{
    "$id": "api",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "UserInfoAlias": {
            "properties": {
                "id": {
                    "type": "string"
                },
                "nick": {
                    "type": "string"
                },
                "token": {
                    "type": "string"
                }
            },
            "required": [
                "id",
                "token"
            ],
            "type": "object"
        }
    }
}


4、封裝一個校驗方法

// validate.ts
import Ajv from 'ajv';
import schema from '.tsJsonSchema.json';

const ajv = new Ajv({ schemas: [schema] });

export function validateDataByType(type: string, data: unknown) {
  console.log(`開始校驗,型別:${type}, 資料:`, data);

  var validate = ajv.getSchema(`api#/definitions/${type}`);
  if (validate) {
    const valid = validate(data);
    if (!valid) {
      console.log('校驗失敗', validate.errors);
    }
    else {
      console.log('校驗成功');
    }
  }
}

5、測試

// index.ts
validateDataByType('IUserInfoAlias', {
  id: '123456';
  token: 'dkhasdkjasdasdasdasdknlknasda';
})

原始碼連結

相關文章