如何优雅地组织校验代码

背景

由于工作中有较多使用正则校验的地方,需要有一个统一的出口去归纳整理校验,故而在此记述

代码实现

工具函数准备

新建文件 validator.ts

interface ValidatorFn {
    (rule: any, value: any, callback: Function): any;
}

class Rule {
    public reg!: RegExp
    public tip!: string

    constructor(reg: RegExp, tip: string) {
        this.reg = reg
        this.tip = tip
    }

    public make() {
        const { reg, tip } = this
        const res: ValidatorFn = (rule, value, callback) => {
            if (reg.test(value)) {
                callback()
            } else {
                callback(new Error(tip))
            }
        }
        return res
    }

    get value() {
        return this.make()
    }
}

class RuleGroup {
    public rules: Rule[] = []

    constructor(...rules: Rule[]) {
        this.rules = rules
    }

    public make() {
        const res: ValidatorFn[] = []

        this.rules.forEach(v => {
            res.push(new Rule(v.reg, v.tip).value)
        })

        return res
    }

    get value() {
        return this.make()
    }
}
/** 字符长度 */
const length = (min?: number, max?: number): Rule => {
    min = min === undefined ? 0 : min
    max = max === undefined ? Infinity : max

    let tip = ''
    let reg: RegExp
    if (max < Infinity) {
        tip = `字符长度不超过${min} - ${max}`
        reg = new RegExp(`^.{${min},${max}}$`)
    } else {
        tip = '字符长度不少于 ' + min
        reg = new RegExp(`^.{${min},}$`)
    }
    return new Rule(reg, tip)
}

/** 数字取值范围  */
const range = (min?: number, max?: number): ValidatorFn => {
    min = min === undefined ? 0 : min
    max = max === undefined ? Infinity : max

    return (rule, value, callback) => {
        const val = Number(value)
        if (val < min) {
            return callback(new Error(`取值不得小于` + min))
        }

        if (val > max) {
            return callback(new Error(`取值不得大于` + max))
        }

        return callback()
    }
}


编写校验代码


export class Validator {
    public text = new Rule(/^[A-Za-z0-9_]*$/, '仅允许输入数字、字母、下划线').value

    public range: (min: number, max?: number) => ValidatorFn = (min, max) => range(min, max)

    public char36 = new RuleGroup(
        new Rule(/^($|[\w-\s]+$)/, '只能输入字母、数字、空格、下划线或中划线'),
        length(0, 36)
    ).value

}

export const validator = new Validator()


测试代码

function test(fns: ValidatorFn[] | ValidatorFn, value: number | string) {
    const res: ValidatorFn[] = []

    if (Array.isArray(fns)) {
        res.push(...fns)
    } else {
        res.push(fns)
    }
    res.map(fn => fn(null, value, (err) => err && console.error(err, value)))
}

// 测试
test(validator.text, 'xxx')
test(validator.char36, '123456789012345678901234567890')
test(length(0, 10).value, 'dddd')
test(range(0, 10), 0)
test(validator.range(0, 10), '1')
test(new MyValidator().int, -1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值