简体   繁体   中英

return type as function in TypeScript

I have a class named ValidatorHelper :

class ValidatorHelper
{
   public name:string
   public value: any
  
  constructor(name:string,vlaue:any)
  {
     this.name = name
     this.value = value
  }
  toString(): string
  {
     return '"name":"' + this.name + '","value":"' + this.value + '"'
  }
 }

and a class named ValidatorBuilder

 class ValidatorBuilder {
  private validators: ValidatorHelper[] = [];
  public Build(): (name: string, value: string) => string[] {
    //how can I build the return type with this.validators
  }
  public required(): ValidatorBuilder {
    this.validators.push(new ValidatorHelper('required', true));
    return this;
  }
  public pattern(pattern: string | RegExp): ValidatorBuilder {
    this.validators.push(new ValidatorHelper('pattern', pattern));
    return this;
  }

Is there any way to build the return type of Build function with validators ?

Or even better ideas for my ValidatorBuilder

I think you miss the point of validation. Validation checks one element and returns a boolean for the result. You can specify this by an interface.

interface Validator {
  validate: (value: any) => boolean;
}

Now you have different kind of validations. In your example Required and Pattern. Let's define those.

class RequiredValidator implements Validator {
  validate(value: any) {
    return !!value;
  }
}

class RequiredValidator implements Validator {

  regularExpression: RegExp;

  constructor(regularExpression: string | RegExp) {
    this.regularExpression = typeof regularExpression === 'string' ? new RegExp(regularExpression) : regularExpression;
  }

  validate(value: string): boolean {
    return this.regularExpression.test(value);
  }
}

Now you can add your builder. The build step also needs to return a validator or a validate function. After all this is nothing else but a chaining of all stored validations.

class ValidatorBuilder {
  private validators: Validator[] = [];

  public required(): ValidatorBuilder {
    this.validators.push(new RequiredValidator());
    return this;
  }

  public pattern(pattern: string | RegExp): ValidatorBuilder {
    this.validators.push(new PatternValidator(pattern));
    return this;
  }

  public build(): Validator {
    return {
      validate: (value: any) => this.validators.every(validator => validator.validate(value)),
    };   
  }
}

Test it:

const myValidator: Validator = new ValidatorBuilder().required().pattern('[\\d]+').build();

console.log('required fails', myValidator.validate(null));
console.log('pattern fails', myValidator.validate('abc'));
console.log('all ok',  myValidator.validate('123'));

See: https://stackblitz.com/edit/typescript-sb5yny

Please note, that this example still have some bugs. You can easily run into misbehavior, when you pass for example an object. This simple quick and dirty example is only for demonstration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM