I want to sort an array of objects by either a string or a number. If it is a string, I want to call .toLowerCase()
on it first. I’m making that distinction using typeof
in the condition of a ternary statement.
interface ObjectProps {
sortFoo: string,
sortBar: number
}
const sortBy: "sortFoo" | "sortBar" = getSortKey();
const sortList = (...args: ObjectProps[]): number => {
const compare: (string | number)[] = args.map(
(arg: ObjectProps): string | number => typeof arg[sortBy] === 'string' ? arg[sortBy].toLowerCase() : arg[sortBy]
);
return compare[0] < compare[1] ? -1 : 1;
}
const objects: ObjectProps[] = getArrayOfObjects().sort(sortList);
This code will run just fine, but TS flags .toLowerCase()
with this error:
TS2339: Property toLowerCase does not exist on type string | number
Property toLowerCase does not exist on type number
How do I tell the TS engine that if typeof myVar === 'string'
evaluates as false, then myVar
is not a string?
I tried replacing the ternary with a full if
clause, as in this tutorial (scroll down to the section titled "Unknown"), but TS still showed the same error. Not sure what else to try.
2
Answers
Looks like Typescript only performs that type narrowing on a variable, not necessarily a property that you’re accessing. So you just need to store the property in a variable first, something like this:
try this hopefully this will help you