Typescript使用函数中的第一个参数从接口中查找第二个参数的类型

问题描述 投票:0回答:1

是否有可能使Typescript根据接口确定此回调的参数类型?

export interface MiddlewareEvent {
    onNewAccount: (accountId: string, timestamp: number) => void,
    onAccountDelete: (accountId:string, timestamp:number)=>void,
}

 const middlewareMap: Map<keyof MiddlewareEvent,((...arg: any) => void )[]> = new Map();

function registerMiddleWare(
    eventId: keyof MiddlewareEvent,
    middleware: ((...arg: any) => void)
) {
        const existing = middlewareMap.get(eventId);
        if (!existing?.length) {
            middlewareMap.set(eventId, [middleware]);
        } else {
            existing.push(middleware);
        }
}

registerMiddleWare(`onNewAccount`, (accountId: number, datetime: string) => {
    console.log(`Wait, Typescript should have prevented this`)
    console.log(`account Id is string not number`)
    console.log(`datetime has been changed to timestamp and is now a number`)
})

想法是将接口的属性作为字符串(或枚举?)传递给函数作为第一个参数,Typescript应该通过查看该键来找出作为第二个参数的回调参数的类型在界面中。

这将不需要用户每次手动传递通用类型参数。

javascript typescript callback
1个回答
1
投票

当然,您只需要一个推断的泛型函数。让它推断要传入的eventId,然后根据该键钻入MiddlewareEvent

function registerMiddleWare<EventName extends keyof MiddlewareEvent>(
    eventId: EventName,
    middleware: MiddlewareEvent[EventName]
) { /* ... */ }

registerMiddleWare(`onNewAccount`, (accountId: number, datetime: string) => {})
// Argument of type
//   '(accountId: number, datetime: string) => void'
// is not assignable to parameter of type
//   '(accountId: string, timestamp: number) => void'

Playground

© www.soinside.com 2019 - 2024. All rights reserved.