Typescript and filter Boolean
If you really don't want to change the generated JavaScript, and instead prefer to force the TypeScript compiler to recognize that Boolean
is serving as a guard against false
values, you can do this:
type ExcludesFalse = <T>(x: T | false) => x is T;
var b: { value: number; }[] = a
.map(x => x != null && { value: x })
.filter(Boolean as any as ExcludesFalse);
This works because you are asserting that Boolean
is a type guard, and because Array.filter()
is overloaded to return a narrowed array if the callback is a type guard.
The above (Boolean as any as ExcludesFalse
) is the cleanest code I could come up with that both works and doesn't change the generated JavaScript. The constant Boolean
is declared to be an instance of the global BooleanConstructor
interface, and you can merge an ExcludesFalse
-like type guard signature into BooleanConstructor
, but not in a way that allows you to just say .filter(Boolean)
and have it work. You can get fancier with the type guard and try to represent guarding against all falsy values (except NaN
) but you don't need that for your example.
Anyway, hope that helps; good luck!
You can use functions like this
function nonNullable<T>(value: T): value is NonNullable<T> {
return value !== null && value !== undefined;
}
type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T; // from lodash
function truthy<T>(value: T): value is Truthy<T> {
return !!value;
}
[1, 2, 0, null].filter(nonNullable) // number[]
[1, 2, 0, null].filter(truthy) // number[]
NonNullable - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#predefined-conditional-types