4

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?

1
  • You could try B(arg1 || arg2 || 0) Just to ensure the compiler has a fallback, that never is used. Commented Apr 29, 2019 at 13:13

2 Answers 2

7

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
}
Sign up to request clarification or add additional context in comments.

Comments

2

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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.