Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing null check using if statement in typescript

Tags:

typescript

Having the following code:

function A(arg1?: string, arg2?: number) {
  if (!arg1 && !arg2) {
    throw new Error('At least one of two parameters must be present');
  }
  B(arg1 || arg2);
}

function B(arg3: string | number) {
  // does something. we don't really care
}

Typescript throws the following compilation error for the expression B(arg1 || arg2):

Argument of type 'string | number | undefined' is not assignable to parameter of type 'string | number'.

Type 'undefined' is not assignable to type 'string | number'. ts(2345)

However, in function A I make sure that at least one of the arguments is not undefined, throwing an error in that case. That means that in the expression B(arg1 || arg2) the argument will never be undefined, it will always be either number or string.

Is something wrong in my assumption? Is there any way of making typescript understand it?

like image 564
sebbab Avatar asked Jan 01 '23 01:01

sebbab


2 Answers

If you were doing a truthy check on a single value TS would indeed correctly infer that the value is no longer undefined

if (arg1) {
  arg1; // arg1: string
}

When you check two variables though, TS doesn't know for certain that either of them individually are truthy, so arg1 and arg2 are still string | undefined and number | undefined respectively.

One option is to assign arg1 || arg2 to a variable before the if statement so the truthy inference works correctly.

function A(arg1?: string, arg2?: number) {
    const arg = arg1 || arg2; // arg: string | number | undefined
    if (arg) {
        // arg: string | number
        B(arg);
    } else {
        throw new Error('At least one of two parameters must be present');
    }
}

function B(arg3: string | number) {
    // does something. we don't really care
}
like image 166
Aron Avatar answered Feb 19 '23 01:02

Aron


A new ! post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact.

What's new

If you sure that at least one of args is not undefined, you could use ! syntax like this:

function A(arg1?: string, arg2?: number) {
  if (!arg1 && !arg2) {
    throw new Error('At least one of two parameters must be present');
  }
  B(arg1! || arg2!); // In compile time `arg1` and `arg2` are not `undefined`, in runtime maybe, but you sure the case  never come true :)
}

function B(arg3: string | number) {
  // does something. we don't really care
}
like image 33
hoangdv Avatar answered Feb 19 '23 03:02

hoangdv