I'm trying to do the following:
interface RgbColor {
r: number;
g: number;
b: number;
}
function rgbToHex(r: RgbColor, g?: undefined, b?: undefined): string
function rgbToHex(r: number, g: number, b: number): string
function rgbToHex(r: number|RgbColor, g?: number, b?: number): string {
if (r instanceof Object) {
// must be RgbColor
g = r.g;
b = r.b;
r = r.r;
}
// A) r was an RgbColor and we've already set r, g, and b to numbers in the if block
// B) we're meeting the second overload and r, g, and b are all numbers
// either way we know they are all numbers now
let rHex = r.toString(16);
let gHex = g.toString(16); // ERROR: Object is possibly 'undefined'.
let bHex = b.toString(16); // ERROR: Object is possibly 'undefined'.
if (rHex.length == 1) rHex = "0" + rHex;
if (gHex.length == 1) gHex = "0" + gHex;
if (bHex.length == 1) bHex = "0" + bHex;
return "#" + rHex + gHex + bHex;
}
I'm getting the errors on the lines indicated by ERROR comments.
From a javascript perspective the function is fine:
function rgbToHex(r , g, b) {
if (r instanceof Object) {
g = r.g;
b = r.b;
r = r.r;
}
let rHex = r.toString(16);
let gHex = g.toString(16);
let bHex = b.toString(16);
if (rHex.length == 1) rHex = "0" + rHex;
if (gHex.length == 1) gHex = "0" + gHex;
if (bHex.length == 1) bHex = "0" + bHex;
return "#" + rHex + gHex + bHex;
}
rgbToHex({ r: 120, g: 50, b: 5 }) // "#783205"
rgbToHex(120, 50, 5) // "#783205"
My question is how can I setup the function signatures such that this just works without having to do any casting and without setting up any redundant variables in the function body. i.e. I want to avoid doing let gVal: number = g || (r as any).g;.
The other alternative would be to split this into two function and have one call the other; but I wouldn't do that with javascript, so it seems wrong that I'd have to do that with typescript.
Sorry if this is a duplicate. I spent a couple of hours looking through similar questions but I couldn't find anything that addressed this issue.