Lets assume we have the following shapes array setup:

```
type Circle = { radius: number };
type Square = { size: number };
type Shape = Circle | Square;
const shapes: Shape[] = [{ radius: 10 }, { size: 20 }, { radius: 15 }];
```

Now we want to filter circles:

`const circles = shapes.filter((shape) => "radius" in shape);`

However TypeScript still doesn't actually know we're left with circles, if we attempt to do the following:

`const radius = circles[0].radius; // Property 'radius' does not exist on type 'Shape'.`

So we can use type predicates to give TypeScript a hint:

```
const isCircle = (shape: Shape): shape is Circle => 'radius' in shape;
const circles = shapes.filter(isCircle);
Now the following works:
const radius = circles[0].radius; // const radius: number
```

But what happens if our type predicate is wrong?

```
// TypeScript doesn't actually validate this is a circle, it acts more like a cast
const isCircle = (shape: Shape): shape is Circle =>
"some-other-property" in shape;
const circles = shapes.filter(isCircle);
// This actually isn't true at all, `radius` might not exist
const radius = circles[0].radius; // const radius: number
```

So this isn't great. There is another option though which will allow TypeScript to correctly determine the narrowed type without having to use a type predicate. To make it work we'll:

- Create a mapped array of
`.shapes`

. For each item we will perform type narrowing and then return the narrowed type or`undefined`

- Filter out all
`undefined`

records

And we're left with an array of narrowed types, no type predicates needed!

**Warning:** If you're dealing with filtering very large datasets you're probably better off sticking with type predicates.

```
const typesafeFilter = <T, TReturn>(
items: T[],
filter: (item: T) => TReturn | undefined
): TReturn[] =>
items.map(filter).filter((item): item is TReturn => Boolean(item));
const circles = typesafeFilter(shapes, (shape) =>
"radius" in shape ? shape : undefined
);
// TypeScript figured out this was a circle!
const radius = circles[0].radius; // const radius: number;
```

Better yet if we make a typo, TypeScript will complain:

```
const circles = typesafeFilter(shapes, (shape) =>
"radius-typo" in shape ? shape : undefined
);
const radius = circles[0].radius; // Property 'radius' does not exist on type '(Circle & Record<"radius-typo", unknown>)
```

Then go about with your other business.