How to tell TypeScript there is no undefined in Array?

Viewed 926

I have the error: Type (string | undefined)[] is not assignable to type string | string[] | undefined, because my function this.errors get the type string | string[] | undefined. But before to return the array I filtered it with undefined. It means there is no undefined. And the value can be string or undefined. The definition of setErrors return array of errors. This is my error:enter image description here

This is my function:

    this.setErrors(() => {
      const errors = validators.map(val => val(this.inputValue));
      const filteredErrors = errors.filter(el => el);

      return filteredErrors && filteredErrors.length !== 0 ? filteredErrors : undefined;
    });

Validators:

const REGEXP_UPPERCASE = /[A-Z]/;
const REGEXP_LOWERCASE = /[a-z]/;
const REGEXP_ONE_DIGIT = /.*[0-9].*/;

export const newPasswordValidators = (args: { min: number; max: number }) => {
  const { min, max } = args;
  return {
    minMaxLength: (value?: string) => value && value.length < min || value.length > max ? 'Not valid length' : undefined,
    requiredToFill: (value?: string) => !value ? 'Required to fill.' : undefined,
    uppercaseLetter: (value?: string) => value && !REGEXP_UPPERCASE.test(value) ? 'Use at least one uppercase letter.' : undefined,
    lowercaseLetter: (value?: string) => value && !REGEXP_LOWERCASE.test(value) ? 'Use at least one lowercase letter.' : undefined,
    atLeastOneDigit: (value?: string) => value && !REGEXP_ONE_DIGIT.test(value) ? 'Use at least one digit.' : undefined,
  };
};

Super class method:

  public setErrors(errors: string | string[] | undefined | (() => (string | string[] | undefined))) {
    this._errors = errors;
  }

Can you tell me please how can I get rid from this error?

2 Answers

As far as I understand, you have two values:

const foo: (string | undefined)[] | undefined = 'hello foo';
const bar: string | string[] | undefined = 'hello bar';

As You may have noticed, variable bar can be string, whereas variable foo can't. variable foo can be an array of strings or undefineds or undefined at all.

Simplier example:

const fn = (arg: string)=>arg;
const result = fn(undefined) // error;

You cant pass undefined to function which expects string

I think you should adjust your types or allow one of your values to be a string type; Please keep in mind, you can use any type or as operator, but it is a cheating.

Did you ever hear of typecasting (to be exact, it's more a type assertion in TS due to JS' dynamic nature)? Sounds like this is what you need here, there are two ways to do it which produce basically the same result:

const x: string[] = <string[]>strAndUndefinedArr;
const y: string[] = strAndUndefinedArr as string[];

This works everywhere, you can also do stuff like

functionCall(<string[]>arr); //or functionCall(arr as string[])

You can read more on this here

Related