There is a function that can return two different types, as shown below:
function doSomething(obj: {a: string, b?: string}): string | number {
if (obj.b) {
return 'something'
}
return 1
}
When the function is called with an object containing the optional property b
, it always returns a string
.
If the function is called with an object that does not have the optional property b
, it always returns a number
.
Currently, when calling the function, the return type is always a union of string
and number
:
const result = doSomething({a: 'a', b: 'b'})
// ^ string | number
Is there a way to make the function return the correct type based on the input argument?
const result1 = doSomething({a: 'a', b: 'b'})
// ^ string
const result2 = doSomething({a: 'a'})
// ^ number
I've attempted to use conditional types without success:
type ConditionalType<T> = T extends { b: string} ? string : number
type Argument = {
a: string,
b?: string,
}
function doSomething<T extends Argument>(obj: T): ConditionalType<T> {
if (obj.b) {
return 'something'
}
return 1
}
const result = doSomething({a: 'a', b: 'b'})
Even after letting TypeScript infer the type, the result remains a union type:
function doSomething(obj: {a:string,b?:string}) {
if (obj.b) {
return 'something'
}
return 1
}
const result = doSomething({a: 'a', b: 'b'})
// ^ "something" | 1