I am working with the following types:
type Fruits = {
type: 'banana' | 'peach' | 'kiwi',
price: null | string;
}
type FruitsWithNonNull = Pick<Fruits, 'type'> & {
price: NonNullable<Fruits['price']>
}
const fruits:Fruits[] = [{type:'banana', price:null}, {type:'peach', price:null},{type:'peach', price:'12'}]
const filteredFruits:FruitsWithNonNull[] = fruits.filter(fruit => fruit.price !== null);
I get this error from filteredFruits
:
Type 'Fruits[]' is not assignable to type 'FruitsWithNonNull[]'.
Type 'Fruits' is not assignable to type 'FruitsWithNonNull'.
Type 'Fruits' is not assignable to type '{ price: string; }'.
Types of property 'price' are incompatible.
how can I convince typescript that when the filtering of the fruits is happening then the price is guaranteed to be there?
here is a link to the typescript playground
I am not that confident with typescript yet so not sure what the solution is here.
You can accomplish this with a user-defined type guard
type Fruits = {
type: 'banana' | 'peach' | 'kiwi',
price: null | string;
}
type FruitsWithPrice = Pick<Fruits, 'type'> & {
price: string;
}
const fruits: Fruits[] = [{type:'banana', price:null}, {type:'peach', price:null},{type:'peach', price:'12'}];
const isFruitWithPrice = (x: any): x is FruitsWithPrice => {
return x?.price !== null;
}
const filtered: FruitsWithPrice[] = fruits.filter(isFruitWithPrice)