Imagine having a function that retrieves the return value of a provided getIdentifier
function. This function is necessary, except in cases where the item
contains an id
property, in which case we can simply read that value.
type FuncArg<T> = T extends { id: string }
? { item: T; getIdentifier?: (item: T) => string }
: { item: T; getIdentifier: (item: T) => string };
type withId<T> = T & { id: string };
const getFoobar = <T>(arg: FuncArg<T>) => {
return arg.getIdentifier ? arg.getIdentifier(arg.item) : (arg.item as withId<T>).id;
};
So far, so good. Now, consider another function that takes an item as input, checks for an id
, and if not found, provides a random generator for getIdentifier
.
const getFoobar2 = <T>(item: T) => {
if ('id' in item) return getFoobar({item: item as withId<T>});
return getFoobar({item: item, getIdentifier: () => Math.random().toString()});
}
Unfortunately, the type checking fails in this last example, and I'm struggling to find a solution. I've experimented with conditional and union types, as well as function overloads, but keep encountering similar issues. Can you point out what might be missing here?