function uhoh (x:string|number) {
if (typeof x === 'string') {
return x.length
} else {
return 'bar'
}
}
const a = uhoh('foo') //= string | number
const b = uhoh(3) //= string | number function uhoh (x:string|number) {
if (typeof x === 'string') {
return x.length
} else {
return 'bar'
}
}
const a = uhoh('foo') //= string | number
const b = uhoh(3) //= string | number function uhoh (x:string|number) {
if (typeof x === 'string') {
return x.length
} else {
return 'bar'
}
}
function uhoh (x:string): number;
function uhoh (x:number): string;
const a = uhoh('foo') //= number
const b = uhoh(3) //= string uhoh : ((x : string) => number) & ((x : number) => string)
And get what you expect: const a = uhoh('foo') // : number
const b = uhoh(3) // : stringerror TS2354: No best common type exists among return expressions.
So at least it detects the problem. However the type inference algorithm should arguably return a union type here.
I find it good practice to always specify the return type of functions anyway. Then it will pick up cases where you return a type you didn't intend to; instead of just using a more general type it will tell you about the inconsistency.
I suppose the reasoning is that, when adding types to js, this is exactly the kind of bad behaviour you want to catch. But I'm not sure, perhaps there are just technical implications for not inferring union return types.
And the actual type of the const won't be `string | number` -- it will be `any`.
MaulingMonkey[1] has the right idea, though.