当前位置: 首页 > Web前端 > JavaScript

使用TypeScript验证运行时数据

时间:2023-03-26 20:24:22 JavaScript

背景对于前端程序员来说,常见的开发流程是:前端与前端约定接口,后端根据接口提供接口文档。根据接口编写TypeScript类型定义。还是翻车,js报错:cannotreadtheproperty'xx'ofnull,显然前端没有处理null值,背锅TT。但是回头看接口文档,跟后端同学约定好的返回对象,实际返回的是null,这怪罪不是一个人能扛得住的。那么如何才能尽早发现这类问题呢?一种解决方案是:将TypeScript类型定义转换为JSONSchema,并使用JSONSchema来验证数据的正确性。针对上述解决方案制作了一个demoJSONSchema。JSONSchema是一种JSON对象,用于描述和验证JSON对象的格式。例如,以下JSON模式:{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"number"},“爱好”:{“类型”:“数组”,“项目”:{“类型”:“字符串”}}},“必需”:[“年龄”,“爱好”,“姓名”],“$模式":"http://json-schema.org/draft-07/schema#",}描述了这样一个JSON对象:type-typeisobject有四个属性-propertiesname:typeisstringage:typeisnumberhobby:typeisArray属性是否必填-必填:name,age,hobby都是必填项。下面的JSON对象满足这个JSONSchema:{"name":"Tom","age":1,"hobby":["coding"]},可见JSONSchema还是很容易理解的,但是它的描述语法还是有一定的学习成本的。强烈建议通过jsonschema库的例子学习相关语法。此外,您还可以参阅UnderstandingJSONSchema。有了JSONSchema,如何用它来验证JSON对象的合法性呢?这里用到了刚刚提到的jsonschema库。一个简单的使用示例如下:varValidator=require('jsonschema').Validator;varv=newValidator();varinstance=4;varschema={"type":"number"};console.log(v.validate(实例,模式));现在我们可以根据JSONSchema来验证后端返回的数据格式是否正确,但是手动为每个接口编写JSONSchema是不现实的。我们很自然地想知道TypeScript的接口类型是否可以将定义转换为JSONSchema?TypeScriptInterface->JSONSchema幸运的是,已经有一个typescript-json-schema库可以帮助我们解决这个问题。这是一个简单的用法示例:importpathfrom"path";import*asTJSfrom"typescript-json-schema";constsettings:TJS.PartialArgs={required:true};//optionallypasstscompileroptionsconstcompilerOptions:TJS.CompilerOptions={strictNullChecks:true};//解析接口定义文件:index.tsconstprogram=TJS.getProgramFromFiles([path.join(__dirname,'./apis/index.ts')],compilerOptions,);//将接口“IApi1”转换为schema,传入“*”将转换所有interfaceletsschema=TJS.generateSchema(program,"IApi1",settings)||{};经过一次操作,可以将如下接口转化为文章开头给出的示例JSONSchema:interfaceIApi1{name:string;年龄:数字;爱好:字符串[];}然后使用node将新获取的schema保存到json文件中:fs.writeFileSync(path.join(__dirname,"./json-schema","schema.json"),schema);然后就可以使用相应的JSONSchema验证后端数据了:.then(res=>{constvalidateRes1=v.validate(res,apiSchema)console.log(validateRes1);});完整示例参见:demo项目中的实践1.如何组织分散的接口类型定义?我个人比较喜欢的方式是:把所有的接口定义和类型定义都写在apis.ts文件里,这样转换JSONSchema的时候就可以处理这个文件。2.如何将类型定义自动转换为JSONSchema?在pre-commit阶段使用husky进行转换工作,进一步使用lint-staged判断当前commit是否涉及对接口定义文件的更改,如果有更改则进行转换。关于脚本编写:先创建脚本touchscripts/transfer.jstransfer.js编写TS转JSONSchema的逻辑,在package.json中添加脚本:"scripts":{"transfer":"nodescripts/transfer.js"}或者在预提交中执行脚本。3、什么时候查资料?这里我想到了两个场景:在生产中:对于一些关键的接口,在接口返回数据后调用验证逻辑。如果验证错误,需要做两件事:第一是将错误的数据转换成正确的备份数据,以防页面挂掉;二是报错;测试时:编写各种测试用例测试后端接口,验证返回数据的正确性,这样就不需要用人眼去检查数据是否正确。