在尝试使用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上查看代码。
答案 0 :(得分:2)
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);
}