首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建类型安全的链式验证

创建类型安全的链式验证
EN

Stack Overflow用户
提问于 2020-03-18 19:35:19
回答 3查看 43关注 0票数 2

在这个阶段,我需要对一些数据执行几个链式验证,到目前为止,我一直在做以下工作:

代码语言:javascript
复制
// 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,比如下面的例子,它接收数据并用每个链式函数验证它(同时返回正确的类型):

代码语言:javascript
复制
validate(data).isData().isString().isLength(3)

或者类似的东西。我被困在弄清楚如何使这种链式应用程序接口,同时也以类型安全的方式管道数据到每个验证器,即在isString数据不应该是未定义的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-03-18 19:47:00

创建一个类型验证器类,并让函数返回类范围。在Builder Pattern中可以看到一个突出的用法。

代码链接:TypeScript Play

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2020-03-18 19:56:31

一种不同的方法是使用某种原语一元验证链,其中链中的每个函数都执行验证,并返回错误(如果验证失败)或已传递的参数(如果验证成功)。

然后,您可以将这些函数组合在一起,以获得完整的验证。

请注意,这个简单的实现破坏了准确的单个检查失败的信息,如果您想保留需要使用实际Monads的信息:)

代码语言:javascript
复制
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)
)

Playground link

票数 0
EN

Stack Overflow用户

发布于 2020-03-18 20:10:32

试试这个:

代码语言:javascript
复制
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());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60738695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档