@0x4d6165 You're not missing anything! This is a common problem and is not obvious. `.filter()` has an usual type signature.
Here's how I'm setting things up:
```
type Foo = { a: number };
const arr1: Array<Foo | undefined> = [{a: 1}, undefined, {a: 2}]
```
Given this, type inference for `arr1.filter` gives this type:
```
(method) Array<Foo | undefined>.filter<S>(predicate: (value: Foo | undefined, index: number, array: (Foo | undefined)[]) => value is S, thisArg?: any): S[]
```
The predicate for `filter<S>` takes `Foo | undefined` as an argument, but instead of having `boolean` as its return type, it has the return type `value is S`. This is a [type predicate](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates)
There's two "fun" things about type predicates: they generally aren't inferred, and they generally aren't safely checked.
If you want to narrow the type in the filter you can tell TS to do the narrowing by explicitly using a type predicate:
```
const arr2 = arr1.filter((x): x is Foo => Boolean(x));
```
Now `arr2` has the type `Array<Foo>`. However, because TS doesn't check type predicates, you can also do this:
```
const arr3 = arr1.filter((x): x is undefined => Boolean(x))
```
Identical logic, but now TS thinks that `arr3` has the type `Array<undefined>`!
So in general yes, TS is missing something here. The features you want exist, but they aren't safe to use.
[playground link](https://www.typescriptlang.org/play/?ssl=5&ssc=60&pln=5&pc=1#code/FAFwngDgpgBAYgewTAvDA3jAhgLhgOwFcBbAIygCcYBfAbmAGMF8BnEbCigRjwEFOsYADyJkAHxiF8AEygAzAJb4o0gHyoYAbXS4YXagBpJM+UpVGdeAEzUAuvSat2WTlY0vuAOkUAbEJQAKAIAPAEo8YJgFFngkVHUAISQfKCx8ENDQh2Y2DgoAZndOLm8FP0CMiKiYqVlFZWl4mCSEFLSM0KA)