在这个阶段,我需要对一些数据执行几个链式验证,到目前为止,我一直在做以下工作:
// validation.ts
function isData(data: any) {
return Boolean(data);
}
function isString(data: any) {
return typeof data === "string";
}
function isLength(data: any, length: number) {
return data?.length === length;
}然后我会逐个调用它们,但它会变得有点单调乏味。理想情况下,我会尝试使用链式API,比如下面的例子,它接收数据并用每个链式函数验证它(同时返回正确的类型):
validate(data).isData().isString().isLength(3)或者类似的东西。我被困在弄清楚如何使这种链式应用程序接口,同时也以类型安全的方式管道数据到每个验证器,即在isString数据不应该是未定义的。
发布于 2020-03-18 19:47:00
创建一个类型验证器类,并让函数返回类范围。在Builder Pattern中可以看到一个突出的用法。
代码链接:TypeScript Play
class TypeValidator {
data: any;
constructor(data: any) {
this.data = data;
}
isString() {
if (typeof(this.data) === 'string') {
return this;
} else {
throw Error('[ValueError] Not a string')
}
}
isLength(len: number) {
if (this.data.length === len) {
return this;
} else {
throw Error('[ValueError] Not of length ' + len)
}
}
}
const tv = new TypeValidator('test')
console.log(tv.isString().isLength(4));测试1
tv.isString().isLength(3);
VM30:19 Uncaught Error: [ValueError] Not of length 3
at TypeValidator.isLength (eval at <anonymous> (main-3.js:1239), <anonymous>:19:19)
at eval (eval at <anonymous> (main-3.js:1239), <anonymous>:24:27)
at main-3.js:1239测试2
const tv = new TypeValidator(['abx'])
tv.isString();
VM31:11 Uncaught Error: [ValueError] Not a string
at TypeValidator.isString (eval at <anonymous> (main-3.js:1239), <anonymous>:11:19)
at eval (eval at <anonymous> (main-3.js:1239), <anonymous>:24:16)
at main-3.js:1239发布于 2020-03-18 19:56:31
一种不同的方法是使用某种原语一元验证链,其中链中的每个函数都执行验证,并返回错误(如果验证失败)或已传递的参数(如果验证成功)。
然后,您可以将这些函数组合在一起,以获得完整的验证。
请注意,这个简单的实现破坏了准确的单个检查失败的信息,如果您想保留需要使用实际Monads的信息:)
type Validation<A> = "Invalid" | A
function isData<D>(data: D): Validation<D> {
return Boolean(data) ? data : "Invalid"
}
function isString<D>(data: D): Validation<D> {
return typeof data === "string" ? data : "Invalid"
}
function isLength(data: any, length: number): Validation<{ length: number }> {
return data?.length === length ? data : "Invalid"
}
declare function pipe<A, B, C, D>(a: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): D
declare function pipe<A, B, C>(a: A, f1: (a: A) => B, f2: (b: B) => C): C
declare function pipe<A, B>(a: A, f1: (a: A) => B): B
const validate = <D>(d: D) => pipe(
d,
isData,
isString,
s => isLength(s, 3)
)发布于 2020-03-18 20:10:32
试试这个:
class Validator {
constructor(private data:string) {
this.data = data;
}
isNotEmpty() {
if (this.data) {
return this;
} else {
throw Error('empty value')
}
}
isString() {
if (typeof(this.data) === 'string') {
return this;
} else {
throw Error('[ValueError] Not a string')
}
}
isLength(len: number) {
if (this.data.length === len) {
return this;
} else {
throw Error('[ValueError] Not of length ' + len)
}
}
}
const validate = new Validator("");
console.log(validate.isNotEmpty());https://stackoverflow.com/questions/60738695
复制相似问题