'Typescript does not understand filter on undefined values in array of objects
I struggle to make typescript understand that I'm already handling the undefined cases of one property (project) in this (shortened) example:
interface Entry {
id: number
project?: Project
isPublished?: boolean
}
entries
.filter(entry => !!entry.project)
.map(entry => ({
title: entry.project.title
}))
(entries is an array of Entrys here) and the compiler complains on the line of entry.project.title on the project property that TS2532: Object is possibly 'undefined' even though I have the filter removing the undefined ones. The other optional property is still optional after the filtering, I thus cannot use Required interface :/
How can I make TS understand the property is definitely defined in the map function?
Thank you
-- Edit: added another optional property / clarification as response to a suggested answer that would make all properties required
Solution 1:[1]
You need to define filter callback as a typeguard and use Required type util to make all interface props required:
type Project = {
title: string
}
interface Entry {
id: number
project?: Project
}
type WithProject = Required<Entry>
declare const entries: Entry[]
entries
.filter((entry): entry is WithProject => !!entry.project)
.map(entry => ({
title: entry.project.title
}))
If you are interested in more type utils please see docs
Solution 2:[2]
Adding onto @captain-yossarian's answer and addressing OP's comment on it, we can make our own utility type to require only a few specific keys:
type Project = {
title: string
}
interface Entry {
id: number
project?: Project
}
type SomeAreRequired<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
type WithProject = SomeAreRequired<Entry, "project">;
declare const entries: Entry[]
entries
.filter((entry): entry is WithProject => !!entry.project)
.map(entry => ({
title: entry.project.title
}))
SomeAreRequired picks all keys in T and makes them required, then adds it to T with the K keys omitted, effectively making only the selected keys required.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | captain-yossarian from Ukraine |
| Solution 2 | hittingonme |
