Reputation: 167
I have a function that looks like this:
function foo(a) {
if(a.optionalProperty === undefined) {
return {
one: 1,
two: 2
}
} else {
return {
one: 1,
two: 2,
optionalResultProperty: "some stuff"
}
}
}
The parameter a is one of the following two types:
SomeType & {
optionalProperty: string
}
// or
SomeType
I would like to specify the return type so that it matches the function definition, meaning when the optionalProperty
is present, the return type should be a certain return type and if it is not present, it should be a different return type.
This is what I have tried so far:
function foo<x extends (SomeType & { optionalProperty: string }) | SomeType>(a: x): x extends (SomeType & { optionalProperty: string }) ? SomeReturnType : Omit<SomeReturnType, "optionalResultProperty"> {
// ..
}
However, this doesn't seem to be correct. It says that the code is not assignable to the type.
What would be the correct way to do this?
Upvotes: 3
Views: 298
Reputation: 55866
What you seem to want here is to overload the function. This should do the job in a more readable way.
type SomeType = {p: string};
type RetOne = { one: number; two: number };
type RetTwo = RetOne & { optionalResultProperty: string };
function foo(a: SomeType): RetOne;
function foo(a: SomeType & { optionalProperty: string }): RetTwo;
function foo(a: SomeType | SomeType & { optionalProperty: string }) {
if ('optionalProperty' in a) {
return {
one: 1,
two: 2,
optionalResultProperty: "some stuff",
};
} else {
return {
one: 1,
two: 2,
};
}
}
// Return type: RetOne
const ret1 = foo({p: 'some'});
// Return type: RetTwo
const ret2 = foo({p: 'some', optionalProperty: '1'});
Link to TypeScript Playground: https://tsplay.dev/wOa66m
Upvotes: 3