首页 > 解决方案 > typescript中函数声明的区别

问题描述

假设我们有这样的代码:

interface Vehicle {
    bicycle(): string;
    car(wheel: number): void;
    bus(passanger: number): {
        name: string;
        age: number;
    }[];
}

type Mapper<K extends keyof Vehicle> = (funcName: K, callback: Vehicle[K]) => void;

interface MapperB {
    <K extends keyof Vehicle>(name: K, callback: Vehicle[K]): any;
}

declare const caller: Mapper<keyof Vehicle>;
declare const callerB: MapperB

或者这里的打字稿游乐场。

当我调用callerand时callerBcaller无法callback根据第一个参数推断类型。实际上,我发现没有办法存档。但callerB一切都做得很好。

caller("bicycle", () => {
    
})// can't give any intellisense

callerB('bus', (passanger) => {
    return [{
        name: 'Jack',
        age: 11
    }]
})// will give perfect hints according to first argument.

所以我想知道这两个声明之间有什么区别,它似乎不是一个错误。

标签: typescripttypescript-typings

解决方案


一种是恰好是函数的泛型类型(Mapper),另一种是泛型函数(MapperB)。

泛型类型在您声明时指定其类型参数,caller因此在您调用caller. K已经是一成不变的,K将是联盟'bicycle' | 'car' | 'bus'。Socallback将被键入为Vehicle['bicycle' | 'car' | 'bus']which 将是所有函数签名的联合,Vehicle其中可能对您想要的内容过于宽容。

泛型函数在调用函数时指定(或推断)其类型参数。所以此时根据参数的类型判断K为just bus,可以更准确的推断出回调参数。

您可以使用类型别名声明泛型函数,但泛型类型参数列表必须在函数上而不是在类型上:

type Mapper = <K extends keyof Vehicle>(funcName: K, callback: Vehicle[K]) => void;

游乐场链接


推荐阅读