dart

How to filter out null values from a Dart list while ensuring type safety?


I'm working with a list in Dart that contains nullable elements. I want to filter out the null values and have a List with non-nullable elements. Here's the code I'm using:

List<int?> t = [1, 2, 3, 4, null, 5];
List<int> tWithOutNulls = t.where((e) => e != null).map((e) => e).toList();

However, this line gives me a type error:

A value of type 'List<int?>' can't be assigned to a variable of type 'List<int>'.

I can fix it by explicitly casting with a non-null assertion:

List<int> tWithOutNulls = t.where((e) => e != null).map((e) => e!).toList();

But I wonder if there’s a more elegant or idiomatic way to achieve this in Dart. For example, in TypeScript, we can use a type guard function like this:

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
    return value !== null && value !== undefined;
}

const array: (string | null)[] = ['foo', 'bar', null, 'zoo', null];
const filteredArray: string[] = array.filter(notEmpty);

Solution

  • In your case you can use whereType<T> method:

    Creates a new lazy Iterable with all elements that have type T.

    The matching elements have the same order in the returned iterable as they have in iterator.

    Like this:

    List<int> tWithOutNulls = t.whereType<int>().toList();
    

    Full example