I am attempting to use a type predicate, specifically the isSomeId function, to narrow down the type of an array of SomeU objects based on the key property. The goal is to find an item with the key equal to Keys.SOME_ID. However, it seems that the isSomeId function is giving me a below error:
A type predicate's type must be assignable to its parameter's type. Type '{ key: Keys.SOME_ID; type: FilterType; value: string; }' is not assignable to type 'SomeU'. Type '{ key: Keys.SOME_ID; type: FilterType; value: string; }' is not assignable to type '{ key: Keys; type: FilterType.ONE_OF; value: string[]; }'. Types of property 'type' are incompatible. Type 'FilterType' is not assignable to type 'FilterType.ONE_OF'.
I have followed the TypeScript documentation on type predicates and created the isSomeId function accordingly. I expected this function to correctly infer the type, but it seems like something is not working as intended.
Additionally, I'm exploring the possibility of inferring the expected type directly from the SomeU type. I attempted to use the Extract utility function for this purpose, but it consistently returns never. To illustrate, I tried transforming the type predicate function to something like the following:
function isSomeId(a: SomeU): a is Extract<SomeU, { key: Keys.SOME_ID }>
Any insights or suggestions on how to fix this issue and get the correct type inference for variable s would be greatly appreciated. Attaching link to the TS playground as well.
enum Keys {
SOME_NAME = "SOME_NAME",
SOME_ID = "SOME_ID",
}
enum FilterType {
EQUAL = "EQUAL",
INCLUDE = "INCLUDE",
ONE_OF = "ONE_OF"
}
type SomeU =
| { key: Keys; type: FilterType.EQUAL, value: string}
| { key: Keys; type: FilterType.INCLUDE, value: string}
| { key: Keys; type: FilterType.ONE_OF, value: string[] };
type A = SomeU[];
function isSomeId(a: SomeU): a is { key: Keys.SOME_ID, type: FilterType, value: string } {
return a.key === Keys.SOME_ID && a.type === FilterType.EQUAL;
}
const someArr: A = [
{ key: Keys.SOME_ID, type: FilterType.EQUAL, value: "some"},
{ key: Keys.SOME_NAME, type: FilterType.EQUAL, value: "some"},
{ key: Keys.SOME_NAME, type: FilterType.ONE_OF, value: ['some']},
];
const s = someArr.find(isSomeId);
Your predicate function is returning
type: FilterTypeinstead oftype: FilterType.EQUAL, which is the main thing I think you should adjust, especially since that is what you are checking in your function body.As the error says, your predicate function's return type must be assignable to whatever your parameter is.
Here is what you are returning (I'm expanding your enums)
That isn't a valid type within
SomeU. Namely,Is not a valid
SomeU.If you somehow did want to return all enums in
type, you'd need to separate out the ones that don't havevalue: string, e.g.My guess is that you just had a typo, but I'm not sure how useful the above predicate function would be.