Reputation: 1136
I have a union type like this:
export type TileType =
| ProductTileType
| CustomTileType
| DealTileType
| LoadingTileType
And a React component that needs to be able to take a prop of type: ProductTileType | CustomTileType | DealTileType
. So I declared that prop with type Exclude<TileType, LoadingTileType>
so as not to allow that type to be used here. The only problem is that ProductTileType
is declared like this:
export interface ProductTileType extends LoadingTileType { ... }
When I exclude LoadingTileType
TS also wants to exclude any type that extends it. How can I avoid excluding types that extend what I want to exclude? Is there another utility type I am not aware of?
Edit:
type MyType = Exclude<TileType, LoadingTileType> | ProductTileType
would be a quick workaround to solve the problem at hand (In this case ProductTileType was the only one extending LoadingTileType) But in the future there might be others types that extend LoadingTileType
. What would be a better way to handle that?
Upvotes: 4
Views: 2210
Reputation: 26324
Let's say we have some drinks:
interface Water { healthiness: 1000 }
interface Lemonade { healthiness: 500 }
interface Tea { healthiness: 1250 } // really it depends on what kind of tea
interface Soda { healthiness: -1000 }
interface Coke extends Soda { fizziness: 1000 }
interface DrPepper extends Soda { fizziness: 800 }
interface Pepsi extends Soda { fizziness: 750 }
type Drinks = Water | Lemonade | Tea | Soda | Coke | DrPepper | Pepsi;
Now, I want a type that is all the drinks, except for the extremely non-specific "Soda" drink.
While I could just exclude that and then bring back the other (more specific) sodas:
type NoGenericSodaBad = Exclude<Drinks, Soda> | Coke | DrPepper | Pepsi;
What I really need is a stricter Exclude
:
type StrictExclude<T, U> = T extends U ? U extends T ? never : T : T;
This type excludes U
and only U
(although if you pass never
it'll for sure break some things) since each member in the union T
must be mutually assignable to U
. That means I can get my drinks without "Soda"!
type NoGenericSodaGood = StrictExclude<Drinks, Soda>;
Upvotes: 4