typescript - 使用枚举重载 TypeScript 函数
问题描述
在尝试使用 TypeScript 实现函数重载以及作为参数传递的枚举以及类型取决于枚举的第二个参数时,我遇到了一个小问题。
例如:
- 如果枚举是
FOO
,那么第二个参数是一个string
类型 - 如果枚举是
BAR
,那么第二个参数是一个number
类型 - 如果枚举是
BAZ
,则没有第二个参数
我拥有的代码如下,但不知何故 TypeScript 会引发错误,因为即使我根据枚举检查第一个参数,intellisense 也不会缩小第二个参数的类型:fieldValue
总是string | number
。
enum ViewName {
FOO = 'foo',
BAR = 'bar',
BAZ = 'baz'
}
function myFunction(viewName: ViewName.FOO, stringValue: string);
function myFunction(viewName: ViewName.BAR, numberValue: number);
function myFunction(viewName: ViewName.BAZ);
function myFunction(viewName: ViewName, fieldValue?: string | number): void {
if (viewName === ViewName.FOO) {
fieldValue = fieldValue.reverse();
}
if (viewName === ViewName.BAR) {
fieldValue *= 2;
}
if (viewName === ViewName.BAZ) {
return console.log('No fieldvalue is supplied by BAZ.');
}
console.log(fieldValue);
}
代码也可以在TypeScript Playground上查看。
解决方案
Typescript 不会根据第一个参数的类型缩小第二个参数的类型。这个功能只是没有在打字稿中实现。
您可以添加额外的检查以if
让编译器缩小fieldValue
function myFunction(viewName: ViewName.FOO, stringValue: string);
function myFunction(viewName: ViewName.BAR, numberValue: number);
function myFunction(viewName: ViewName.BAZ);
function myFunction(viewName: ViewName, fieldValue?: string | number): void {
if (viewName === ViewName.FOO && typeof fieldValue === "string") {
fieldValue = fieldValue.reverse();
}
else if (viewName === ViewName.BAR && typeof fieldValue === 'number') {
fieldValue *= 2;
}
console.log(fieldValue);
}
或者您可以只使用类型断言:
function myFunction(viewName: ViewName.FOO, stringValue: string);
function myFunction(viewName: ViewName.BAR, numberValue: number);
function myFunction(viewName: ViewName.BAZ);
function myFunction(viewName: ViewName, fieldValue?: string | number): void {
if (viewName === ViewName.FOO) {
fieldValue = (fieldValue as string).reverse();
}
else if (viewName === ViewName.BAR) {
fieldValue = (fieldValue as number) * 2;
}
console.log(fieldValue);
}
更大的变化是使用有区别的联合,这将允许编译器以更预期的方式缩小参数的类型:
function myFunction(p: { viewName: ViewName.BAZ }
| { viewName: ViewName.BAR, fieldValue: number }
| { viewName: ViewName.FOO, fieldValue: string }): void {
if (p.viewName === ViewName.FOO) {
p.fieldValue = p.fieldValue.reverse();
}
else if (p.viewName === ViewName.BAR) {
p.fieldValue *= 2;
}
console.log(fieldValue);
}
推荐阅读
- freemarker - 显示日期 - 长格式的三天减去 Freemarker 中的年份
- r - 在 R 中使用相同的管道但不同的列创建多个数据框
- oracle - 如何在句子周围加上引号
- javascript - Reactstrap Navbar 右对齐项目
- asp.net-core - 最佳实践:如何将控制器数据从我的服务中移出并移到我的控制器中?
- android - Kotlin - 如何使用数据类将数据从 firebase 保存到 livedata?
- azure - docker容器给出天蓝色身份验证错误
- python - 尝试登录我的 gmail;imaplib.error: b'[AUTHENTICATIONFAILED] 无效凭据(失败)'
- python - 如何避免文件末尾的新行?
- c# - Flowlayout 在控件之间动态添加控件