打字稿中函数声明的区别

The difference of function declaration in 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

或打字稿游乐场here

并且当我调用callercallerB时,caller无法根据第一个参数推断出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.

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

你的Mapper类型是泛型,returns是非泛型函数(函数中的类型参数在接收到泛型类型参数后被扩展),这意味着Kkeyof Vehicle 而不是您要查找的 specific 键。 MapperB 类型不是泛型,而是有一个泛型函数,这意味着类型变量在函数调用时被扩展,意味着 K 可以调整为 [=15= 的特定键].

一个是泛型​​恰好是函数(Mapper),另一个是泛型​​函数(MapperB)。

泛型类型在您声明 caller 时指定了其类型参数,因此当您调用 caller 时不再发生推理。 K已经是铁板一块了,K就是联合'bicycle' | 'car' | 'bus'。因此 callback 将被键入为 Vehicle['bicycle' | 'car' | 'bus'] ,它将是 Vehicle 中所有函数签名的联合,这可能对您想要的内容过于宽松。

泛型函数在调用函数时指定(或推断)其类型参数。所以当时根据参数的类型决定K只是bus,可以更准确地推断出回调参数。

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

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

Playground Link