使用ReturnType<typeof myFunction>时遇unknown不可赋值给never类型问题
解决TypeScript函数参数类型不兼容问题
问题原因
问题源于函数参数的逆变特性:当你将guard<never>返回的(data: never) => Promise<{ statusCode: number }>赋值给events对象时,Record<string, ReturnType<typeof guard>>中的ReturnType<typeof guard>会默认推断为(data: unknown) => Promise<{ statusCode: number }>(因为泛型Data未指定时默认是unknown)。由于函数参数是逆变的——unknown类型的参数无法赋值给never类型的参数(调用events中的函数时可能传入任意值,但never类型的函数不接受任何参数),因此类型检查失败。
方法一:用void替代never(推荐)
void类型表示函数不使用参数,TypeScript允许将(data: void) => ...赋值给(data: unknown) => ...(调用时传入的参数会被忽略,不会引发问题)。修改代码如下:
function guard <Data>({ handler }: { handler: (data: Data) => Promise<{ statusCode: number }> }) { return async (data: Data) => { const response = await handler(data); return response; }; } const ping = guard<void>({ handler: async () => { return { statusCode: 200 }; } }); export const events: Record< string, ReturnType<typeof guard> > = { ping };
方法二:调整events的类型为联合类型
若坚持使用never,可将events的类型定义为接受never或unknown参数的函数联合类型:
type EventHandler = | (data: never) => Promise<{ statusCode: number }> | (data: unknown) => Promise<{ statusCode: number }>; function guard <Data>({ handler }: { handler: (data: Data) => Promise<{ statusCode: number }> }) { return async (data: Data) => { const response = await handler(data); return response; }; } const ping = guard<never>({ handler: async () => { return { statusCode: 200 }; } }); export const events: Record<string, EventHandler> = { ping };
方法三:类型断言(简单但需谨慎)
直接通过类型断言告诉TypeScriptping的类型与events要求兼容,适合你能确保调用ping时不会传入参数的场景:
function guard <Data>({ handler }: { handler: (data: Data) => Promise<{ statusCode: number }> }) { return async (data: Data) => { const response = await handler(data); return response; }; } const ping = guard<never>({ handler: async () => { return { statusCode: 200 }; } }); export const events: Record< string, ReturnType<typeof guard> > = { ping: ping as ReturnType<typeof guard> };
内容的提问来源于stack exchange,提问作者aprilmintacpineda
相关产品推荐
相关产品推荐

