我正在尝试使用泛型打开 typescript 方法。 有一个带有方法的对象(注释中指出了不同类型的函数参数)
const emailTypes = {
confirmEmail: generateConfirmEmailOptions, // { a: string, b: string;}
restorePassword: generateRestorePasswordOptions, // { a: string, b: number;}
};
输入该对象的键:
export type IEmailTypes = typeof emailTypes;
以及方法本身:
export const getEmailOptions = <T extends keyof IEmailTypes>(emailType: T, emailData: Parameters<IEmailTypes[T]>[0]) =>
emailTypes[emailType](emailData);
现在咒骂(emailData)
,我不明白为什么。
我觉得我做的是正确的事。我将键的名称传递给 T
,然后获取该键的函数参数。
但不,如果类型不同,它会发誓。
我想让它在传输时,例如
emailType
中的 confirmEmail
,TS 准确地告诉了我 emailData
应该是什么
我做错了什么?
*emailTypes
中的方法具有参数类型
最佳答案
检查@jcalz 答案 here .
因此,您要么通过强制转换牺牲类型安全,要么需要重构它以帮助编译器。它可能看起来像 this :
declare const generateConfirmEmailOptions: (opts: { a: string; b: string }) => void
declare const generateRestorePasswordOptions: (opts: { a: string; b: number }) => void
interface Args {
confirmEmail: Parameters<typeof generateConfirmEmailOptions>[0]
restorePassword: Parameters<typeof generateRestorePasswordOptions>[0]
}
type Mapping = { [K in keyof Args]: (opts: Args[K]) => void }
const emailTypes: Mapping = {
confirmEmail: generateConfirmEmailOptions,
restorePassword: generateRestorePasswordOptions,
};
const getEmailOptions = <K extends keyof Args>(emailType: K, emailData: Args[K]) => {
const fn = emailTypes[emailType]
return fn(emailData);
}
是的,有点不幸的是您必须重复一些代码,但显然现在这是唯一 100% 类型安全的方法。让我们看看 TypeScript 的 future 版本会带来什么。
关于带有函数参数的 typescript 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71372485/