Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to say is not in typescript?

I have this type:

(string | undefined)[]

I want to convert this type to:

(string)[]
  1. I want to do that without type casting.
  2. I can’t know the given type in advance, what I know is that it’s an array of stuff.

So I thought I can simply use array.filter() for this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const arr = [1, 2, 3, undefined, 5, 6]
const filteredArray = arr.filter((item) => typeof item !== 'undefined')
console.log(filteredArray) // type of filteredArray (number | undefined)[]

Of course it works in JavaScript, but it TypeScript it doesn’t.

It infers filteredArray (number | undefined)[] even after filtering.

So I remember there was a type guard keyword called is, so I did the following:

function isDefined<T>(value: T | undefined): value is T {
    return value !== undefined;
}
const filteredArray = arr.filter(isDefined)

But it keeps inferring it as (number | undefined)[],

so I thought if there was something like is not, probably I can say:

function isDefined<T>(value: T | undefined): value is not undefined {

Full code of my solution that did not work:

function isDefined<T>(value: T | undefined): value is T {
    return value !== undefined;
}
let arr = [1, 2, 3, undefined, 5, 6]
arr = arr.filter(isDefined)

>Solution :

A good approach to this with reusable code is to create a type guard that can be passed:

function isNotUndefined<T>(item: T | undefined): item is T {
  return item !== undefined;
}

This will ensure that the type of T is properly inferred to be distinct from undefined.

You can check it in this ts playground:

You already did this, so why is it not working, well because typescript is smart. Let us look at your code:

function isDefined<T>(value: T | undefined): value is T {
    return value !== undefined;
}
let arr = [1, 2, 3, undefined, 5, 6] // Type of arr is (number | undefined)[];
arr = arr.filter(isDefined) // Since it is the same variable and the initial typing is compatible, it is not changed

Your origin type when you declare the initial array is (number | undefined)[].
When you perform the filter operation, this typing is still valid, so typescript does not change the array typing.
Therefore, you need to store the result in a new variable in order for a new typing to be infered:

function isDefined<T>(value: T | undefined): value is T {
    return value !== undefined;
}
let arr = [1, 2, 3, undefined, 5, 6] // Type is (number | undefined)[]
let arr2 = arr.filter(isDefined) // Type is number[]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading