繁体   English   中英

带枚举的TypeScript函数重载

[英]TypeScript function overloading with enum

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

例如:

  • 如果枚举为FOO ,则第二个参数为string类型
  • 如果枚举是BAR ,则第二个参数是number类型
  • 如果枚举是BAZ ,则没有第二个参数

我拥有的代码如下,但是以某种方式TypeScript会引发错误,因为即使我在针对枚举检查第一个参数时,intellisense也不会缩小第二个参数的类型: fieldValue始终为string | number 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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM