首页 > 解决方案 > Typescript 通用函数,它根据其他变量提供组件属性

问题描述

这个让我困惑了一段时间,试图创建一个类型安全的电子邮件服务。

我有一个可能的模板名称的枚举:

enum TemplateName {
 EXAMPLE_TEMPLATE = "EXAMPLE TEMPLATE"
 ...
}

我有每个模板的默认设置对象:

type EmailConfig<X = React.ComponentType> = {
 html: X
 subject: string
 ...
}

type EmailMapping: EmailConfig = {
 [key in TemplateName]: EmailConfig
}

const Emails = {
 [TemplateName.EXAMPLE_TEMPLATE]: {
    html: TestTemplate, // THIS IS A REACT FUNCTIONAL COMPONENT
    subject: "This is a test",
    ...rest
 }
 ...
}

我的模板看起来像这样:

export interface TestTemplateProps {
  title?: string
  firstName?: string
  preview?: string
  headline?: string
  site?: string
  ...
}

export const TestTemplate: React.FC<TestTemplateProps> = ({
  title = 'Test Email',
  site = 'My Website',
  preview = 'Important Information from My Site',
  firstName = 'there',
  headline,
  children,
}) => {
  return (
  ...
  )
}

我有一个通用函数,我希望能够传入一个枚举值以及与该枚举值相关的组件的所有道具。

例如

sendEmail(TemplateName.EXAMPLE_TEMPLATE, { ... })

其中 { ... } 输入到 TestTemplateProps 接口

我目前的尝试sendEmail是这样的:

async sendEmail<X extends keyof EmailMapping>(
    template: X,
    opts: React.ComponentProps<typeof Emails[X]['html']>
  ) {
...
}

我试过只是玩玩(老实说,我只是在猜测此时要改变什么),这是我迄今为止最接近的一次。

当我用上面的代码调用 sendEmail 时,它迫使我通过其中一个枚举,但随后出现opts的唯一“打字”是“孩子?” 并且 TestTemplateProps 中没有其他属性,所以我想我很接近了!

TIA

标签: reactjstypescript

解决方案


是的。但我想知道的第一件事是......你是在为数据加载和在接口中传递数据static functionstatic constructor异步数据加载创建一个类......如果是这样......我想知道你的确切问题'重新面对……


推荐阅读