typescript - 有没有办法用可选参数缩小打字稿重载?
问题描述
我正在尝试执行以下操作:
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;
}
我在ERROR
注释指示的行中收到错误。
从javascript的角度来看,该功能很好:
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"
我的问题是如何设置函数签名,这样它就可以正常工作,而无需进行任何转换,也无需在函数体中设置任何冗余变量。即我想避免做let gVal: number = g || (r as any).g;
.
另一种选择是将其拆分为两个函数并让一个调用另一个;但我不会用 javascript 来做这件事,所以我不得不用打字稿来做这件事似乎是错误的。
抱歉,如果这是重复的。我花了几个小时查看类似的问题,但找不到任何解决此问题的方法。
解决方案
问题是,变量g
andb
将始终是 type number | undefined
,如果不声明新变量,就无法永久重新分配它们。
您有 4 个选项:
- 使用 Non-Null Assertion Operator
!
,意思是g.toString(16)
你需要 write 而不是 writeg!.toString(16)
,强制它是 typenumber
。您也可以使用类型转换来解决它。 - 您可以将其分成多个函数,提取 rgb 变量,然后返回原始
rgbToHex
函数。 - 正如@Oblosys 的答案中提到的,您可以使用联合类型。
- 您可以在函数顶部创建一个新对象,在其中填充一个新
RgbColor
对象。
推荐阅读
- vb.net - 带有保存对话框的datagridview数据导出到vb net中的excel
- python - Python错误:(fields.E304)字段的反向访问器与另一个字段的反向访问器冲突
- python - 如何比较数据框中的每个元素
- objective-c - 如何重命名sqlite中的列名在目标c中不起作用
- linux - 进程调度:内核如何更新当前运行进程的need_resched标志?
- javascript - 我无法安装 nodemon 而不会出现错误
- python - 让 if/else 在循环两个范围的列表理解中跳出一个循环
- generics - 通用参数在“供应商” lambda 中丢失,但在“可调用”中没有
- java - 获取图像并放入 jframe 的问题
- arrays - 字典保存错误“SwiftValue encodeWithCoder:]: unrecognized selector sent to instance”