我有一个Express API服务器应用程序和一个React客户端应用程序都在TypeScript中实现。我使用TypeScript接口定义了我的数据模型,并且我在系统的两端使用这些接口。但是,TypeScript接口只是编译时功能,我还需要运行时类型检查,例如验证HTTP POST数据(json)是否符合定义的数据结构。
所以我的问题是,我怎样才能/应该利用TypeScript提供的功能实现运行时对象验证?
答案 0 :(得分:1)
我创建了一个名为Smoke Screen的超轻量级库,它正是这样做的。它利用typescript功能在javascript运行时执行任何类型的对象验证。它不是100%无缝的,因为javascript在运行时不包含任何类型信息,但是由于TypeScript装饰器,这可能很容易实现:
class Person {
@exposed({type: Number})
age: number;
}
// serialize a Person object into a JSON string
const person = new Person();
person.age = 56.8;
const smokeScreen = new SmokeScreen();
smokeScreen.toJSON(person); // -> '{"age":56.8}'
// deserialize a JSON string into a Person object
let json = JSON.stringify({age: 19});
const person2 = smokeScreen.fromJSON(json, Person);
console.log(person2); // -> Person { age: 19 }
// typing validation
json = JSON.stringify({age: "oops"});
smokeScreen.fromJSON(json, Person); // Error: illegal input - property 'age' must be a number
可以设置其他自定义验证器,也支持和强制执行可选参数和空值检查。 我建议阅读更多关于它并试一试。
答案 1 :(得分:1)
您可以尝试一个名为 ts.validator.fluent 的框架/库。 通用对象验证。流利的规则。
https://github.com/VeritasSoftware/ts.validator
NPM套餐:
https://www.npmjs.com/package/ts.validator.fluent
以下是使用框架验证TypeScript模型的示例:
/* Install npm package ts.validator.fluent and then import like below */
import { IValidator, Validator, ValidationResult } from 'ts.validator.fluent/dist';
/*TypeScript model*/
class Person {
Name: string;
}
/* Validation rules */
var validatePersonRules = (validator: IValidator<Person>) : ValidationResult => {
return validator
.NotEmpty(m => m.Name, "Name cannot be empty")
.ToResult();
};
/* Populate model */
var person = new Person();
person.Name = "Shane";
/* Validate model */
/* Sync */
var validationResult = new Validator(person).Validate(validatePersonRules);
/* Async */
var validationResult = await new Validator(person).ValidateAsync(validatePersonRules);
答案 2 :(得分:0)
我意识到这个问题很旧,但是我只是使用装饰器为此目的编写了自己的JSON对象和打字稿验证器。 在此处可用:ts-json-object
示例:
import {JSONObject,required,optional,lt,gte} from 'ts-json-object'
class Person extends JSONObject {
@required // required
name: string
@optional // optional!
@lt(150) // less than 150
@gte(0) // Greater or equal to 0
age?: number
}
let person = new Person({
name: 'Joe'
}) // Ok
let person = new Person({
}) // Will throw a TypeError, because name is required
let person = new Person({
name: 123
}) // Will throw a TypeError, because name must be a string
具有许多其他功能,例如自定义验证等。
答案 3 :(得分:0)
对于TypeScrpit,我也没有找到任何好的解决方案:
所以我创建了一个名为computed-types的库:
const UserSchema = Schema({
name: string,
amount: number,
flags: array.of(string).optional();
});
type User = Type<typeof UserSchema>;
Joi 中的等效代码:
const UserSchema = Joi.object({
name: Joi.string().required(),
amount: Joi.number().required(),
flags: Joi.array().items(Joi.string()),
});
type User = {
name: string;
amount: number;
flags?: string[];
}
在此处查看更多详细信息和示例:https://github.com/neuledge/computed-types