1

With typescript 2.5.2 the following code fails to compile with strictNullChecks:

function ifnull<T>(x: T | null | undefined, def: T): T
{
    return x != null ? x : def;
}

console.log(ifnull(2, 1));

giving the error:

Argument of type '2' is not assignable to parameter of type '1 | null | undefined'.

It seems it infers T to be 1 instead of number. When you compile without strictNullChecks it correctly infers the type number. I am not confident enough to know if this is a bug in Typescript or expected behaviour, so I prefer to ask here before I fill a bug report.

Is this expected? what's the rationale of the strict inference, and is there a way to define ifnull without having to call it as ifnull<number>(...) or ifnull<string>(...)?

Joaquin Cuenca Abela
  • 2,535
  • 22
  • 21

1 Answers1

1

The rationale for the strict inference is probably best explained in this answer by one of TypeScript's core contributors, @RyanCavanaugh. Most of the time you don't want TypeScript to accept two different types for the same type parameter by inferring their union. I don't know why the behavior is different with strictNullChecks turned off, though.

One thing you can do to fix it is to delay the inference of the second parameter, by using & {} like this:

function ifnull<T>(x: T | null | undefined, def: T & {}): T
{
    return x != null ? x : def;
}

console.log(ifnull(2, 1)); // okay

Hope that helps; good luck!

jcalz
  • 264,269
  • 27
  • 359
  • 360