重载签名与其实现签名不兼容

时间:2019-06-29 00:17:11

标签: typescript

我被打字稿卡住了重载功能,确实看过文档一切都有意义,甚至尝试了一下……但是当我实现自己的功能时,它就搞砸了。

async function triggerValidation<Name extends keyof Data>(payload: {
    name: Extract<keyof Data, string>;
    value?: Data[Name];
    forceValidation?: boolean;
  }[]): Promise<boolean>;
async function triggerValidation<Name extends keyof Data>(payload: {
    name: Extract<keyof Data, string>;
    value?: Data[Name];
    forceValidation?: boolean;
  }): Promise<boolean> {
}

enter image description here

所以我想为我的函数接受一个对象或数组,但这给我键入错误。

1 个答案:

答案 0 :(得分:3)

简短回答

  

所以我想为我的函数接受一个对象或数组...

您可以接受数组或对象,而无需使用重载。相反,您可以将union type与用户定义的type guard一起使用,如下所示(playground link):

type Data = {};

type Payload<Name extends keyof Data> = {
    name: Extract<keyof Data, string>;
    value?: Data[Name];
    forceValidation?: boolean;
}

const isArray = <T>(input: any | any[]): input is T[] =>
    input.constructor === Array;

async function triggerValidation<Name extends keyof Data>(
    payload: Payload<Name> | Payload<Name>[]
): Promise<boolean> {

    if (isArray(payload)) {
        console.log(payload.length);
    } else {
        console.log(payload.forceValidation);
    }

    return false;
}

关于函数重载

如果您只想支持某些特定的参数列表组合,则使用a function overload可以带来额外的好处:

function myFunc(p1: string, p2: boolean): void;
function myFunc(p1: number, p2: Date): void;
function myFunc(p1: string | number, p2: boolean | Date): void {
    if (typeof p1 === 'string') {
        console.log(p1, p2);
    } else {
        console.log(p1, p2);
    }
}

现在,如果参数与支持的重载签名不对齐,则会出现错误。

myFunc('foo', false); // works
myFunc(10, new Date()); // works
myFunc('foo', new Date()); // error
myFunc(10, false); // error

尽管它不会提供任何附加值(因为您的函数中只有一个参数),但为完整起见,这里是您原始解决方案在函数重载下的工作方式。

function triggerValidation<Name extends keyof Data>(payload: Payload<Name>): Promise<boolean>
function triggerValidation<Name extends keyof Data>(payload: Payload<Name>[]): Promise<boolean>
async function triggerValidation<Name extends keyof Data>(
    payload: Payload<Name> | Payload<Name>[]
): Promise<boolean> {
    if (isArray(payload)) {
        console.log(payload.length);
    } else {
        console.log(payload.forceValidation);
    }
    return false;
}

在这里,过载部分起作用了,但是没有提供任何附加值,因为没有相关的参数列表要支持。