# Leveraging TypeScript Type Guards for Precise Filtering in Arrays

Since functional programming gained popularity in the JavaScript world, a trio of array methods—namely, `map`, `filter`, and `reduce`—have also risen to prominence. These methods became go-to tools for two primary reasons:

1. They're simpler for doing basic looping with arrays.
    
2. They allow method chaining, resembling the builder design pattern, enhancing coding flexibility.
    

## Problem

However, there's a catch when using TypeScript's `filter`. Consider the following code:

```typescript
const posts = [
    {id: 0, title: "Title 1", content: "Content 1"},
    {id: 1, title: "Title 2", content: "Content 2"},
    {id: 2, title: "Title 3", content: "Content 3"},
    null,
    undefined
];

const filteredPosts = posts.filter(post => post != null);
```

Surprisingly, TypeScript infers `filteredPosts` as a mix of valid posts and null values (i.e. `({id: number, title: string, content: string} | null)[]`). How can we ensure TypeScript infers the correct type?

## Type Guard

Fortunately, TypeScript offers a solution through type guards, expressions that perform runtime checks, ensuring correct type inference. Let's see it in action:

```typescript
// Constructed this type for convenience
type Post = {id: number, title: string, content: string};

const posts = [
    {id: 0, title: "Title 1", content: "Content 1"},
    {id: 1, title: "Title 2", content: "Content 2"},
    {id: 2, title: "Title 3", content: "Content 3"},
    null,
    undefined
];

const filteredPosts = posts.filter((post): post is Post => post != null);
```

Now, TypeScript understands `filteredPosts` as an array containing only `Post` (i.e. `{id: number, title: string, content: string}[]`).

## Improving Reusability

Let's level up our function's versatility using generics and TypeScript's `NonNullable` utility type:

```typescript
const posts = [
    {id: 0, title: "Title 1", content: "Content 1"},
    {id: 1, title: "Title 2", content: "Content 2"},
    {id: 2, title: "Title 3", content: "Content 3"},
    null,
    undefined
];

const chooseNonNullable = <T>(arg: T): arg is NonNullable<T> => arg != null;

const filteredPosts = posts.filter(chooseNonNullable);
```

Now, you can export `chooseNonNullable` and use it as a callback to any `filter` methods to remove both `null` and `undefined`.

## Addressing an Alternative

You might wonder about using the `as` keyword instead of type guards. While possible, it's less reliable as it assumes a type without verification, leading to potential errors. Stick with type guards for accuracy and safety!
