Reputation: 671
Let's say I have a function that returns the return value of a passed-in getIdentifier
function. This function is mandatory, except for when the item
has an id
property because I can fall back to reading just that.
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;
};
All well so far. Let's say I have a second function that passes in an item to the first function, checks if it has an id
and if not it passes in a random generator 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 typechecking breaks in the last example and I have no idea to fix this. I've tried everything from conditional types to union types and function overloads. Everytime I run into similar problems. What am I missing here?
Upvotes: 0
Views: 173
Reputation: 6152
You missed item
parameter in getIdentifier
function signature and looks like it requires explicit as FuncArg<T>
in object declaration. Can't explain better, don't have much experience in Typescript.
const getFoobar2 = <T>(item: T) => {
if ('id' in item)
return getFoobar({ item: item } as FuncArg<T>);
return getFoobar({item: item, getIdentifier: (item: T) => Math.random().toString()} as FuncArg<T>);
}
Upvotes: 1