5

Sorry not sure how to describe my question. Hope the title does not mislead you.

First of all, my issue happens in Angular 11 with strict mode turned on.

Suppose I have an array

let results: T[] = [];

and I have a function as follow and this function does not give any error in Visual Studio Code.

filter = (values: (T | null | undefined)[]): T[] => {
  for(let value of values) {
    if (value !== null && value !== undefined) {
      results.push(value);
    }
  }
}

However, if I extract the condition to another function, such as

isNullOrUndefined = (value: T | null | undefined): bool => {
  return value === null || value === undefined;
}

and then use the function in the above filter function as follow:

filter = (values: (T | null | undefined)[]): T[] => {
  for(let value of values) {
    if (!isNullOrUndefined(value)) {
      results.push(value);
    }
  }
}

I get an error Argument of type 'Nullable<T>' is not assignable to parameter of type 'T'.

Can anyone please help to have a look? Thank you

2 Answers 2

10

The problem is with the typing of the isNullOrUndefined function.

When you use the condition like this

if (value !== null && value !== undefined) {
     results.push(value); // value is only T here

it is used as a type constrain. Typescript automatically constrains the type of value in the if branch to T.

But if you use isNullOrUndefined which returns boolean, Typescript does not check the actual implementation of the function - even if you did not specify the return type explicitly.

if (!isNullOrUndefined(value)) {
  results.push(value); // value still is T | null | undefined
}

In order to make it work, you need to type the isNullOrUndefined as a type contrain as well by specifying the return type as value is null | undefined

isNullOrUndefined = (value: T | null | undefined): value is null | undefined => {
  return value === null || value === undefined;
}

Then Typescript will behave the same as with the original version.

if (!isNullOrUndefined(value)) {
  results.push(value); // value is T
}
Sign up to request clarification or add additional context in comments.

1 Comment

Shouldn't the logic be reversed? Not an expert on Type Guards, but this seems to imply that both null and undefined are T.
-1

A short way is

let show = !input ? false : true;

let input = null;
let show = !input ? false : true;
console.log("show: " + input + " --> " + show);

input = undefined;
show = !input ? false : true;
console.log("show: " + input + " --> "  + show);

input = false;
show = !input ? false : true;
console.log("show: " + input + " --> "  + show);

input= true;
show = !input ? false : true;
console.log("show: " + input + " --> "  + show);

returns

show: null --> false
show: undefined --> false
show: false --> false
show: true --> true

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.