使用枚举重载TypeScript函数

使用枚举重载TypeScript函数,typescript,enums,overloading,Typescript,Enums,Overloading,我在尝试使用TypeScript实现函数重载时遇到了一个小问题,该重载与作为参数传递的枚举以及类型取决于枚举的第二个参数结合使用 例如: 如果枚举是FOO,则第二个参数是字符串类型 如果枚举为条形,则第二个参数为编号类型 如果枚举是BAZ,则没有第二个参数 我的代码如下所示,但不知何故,TypeScript抛出了一个错误,因为即使在我针对枚举检查第一个参数时,intellisense也没有缩小第二个参数的类型:fieldValue始终是string | number enum ViewNam

我在尝试使用TypeScript实现函数重载时遇到了一个小问题,该重载与作为参数传递的枚举以及类型取决于枚举的第二个参数结合使用

例如:

  • 如果枚举是
    FOO
    ,则第二个参数是
    字符串类型
  • 如果枚举为
    条形
    ,则第二个参数为
    编号
    类型
  • 如果枚举是
    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不会根据第一个参数的类型缩小第二个参数的类型。这个特性只是没有在typescript中实现

您可以在
if
中添加额外的检查,让编译器缩小
字段值的类型

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);
}

我认为重载只适用于函数的调用者;在内部,这只是您提供的最后一个定义。@jornsharpe您是正确的:调用函数重载时,函数重载似乎起作用(因此可以有特定的参数组合),但是这种类型的缩小并没有传递到函数本身:)非常感谢您花时间回答我的问题:我不知道TypeScript不能根据函数重载推断/缩小其他参数的类型。这消除了我的疑虑:)