带有函数参数的 typescript 泛型

标签 typescript typescript-typings typescript-generics

我正在尝试使用泛型打开 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 应该是什么

我做错了什么?

为了清楚起见,我将附上屏幕截图。 enter image description here

*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/

相关文章:

TypeScript 泛型 - 期望类型参数是枚举,并引用它的键

javascript - 如何在 TypeScript 中返回具有此自定义类型的 Promise?

javascript - angular2 http拦截器和注入(inject)SlimLoadingBarService不起作用?

angularjs - Angular 指令依赖注入(inject) - TypeScript

d3.js - Typescript 期望从 d3.nest().rollup() 中的辅助函数返回 undefined

typescript - 将 slick-carousel 与 typescript 一起使用

typescript - 如何输入一个 typescript 函数,该函数将对象数组作为第一个参数,并将对象上预期的特定属性作为参数?

typescript - typeorm 自定义存储库在使用 extends Repository<> 时不起作用 "Cannot read property ' findOne' of undefined"

typescript - 管道 "|"符号导致 typescript 定义文件中出现错误

reactjs - 使用 React、Typescript 和 Webpack 显示静态图像