You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Typescript泛型函数如何根据模板枚举推导对应React组件Props类型

问题根源

你当前的类型定义把每个模板对应的具体组件类型抹除了:

  1. 原EmailMapping定义语法错误且类型过宽,所有key对应的html字段都被推导为通用的React.ComponentType,TS无法关联到具体的组件Props
  2. Emails常量没有绑定具体类型,泛型信息丢失后ComponentProps只能识别到React.FC默认带的children属性

修正方案

1. 修正类型与常量定义(推荐TS4.9+,使用satisfies关键字保留精确类型)

import type { ComponentType, ComponentProps } from 'react'

enum TemplateName {
  EXAMPLE_TEMPLATE = "EXAMPLE TEMPLATE"
  // 其他模板枚举值
}

type EmailConfig<X extends ComponentType = ComponentType> = {
  html: X
  subject: string
  // 其余配置字段
}

// 先定义Emails常量,用satisfies约束结构符合要求,同时保留每个模板的具体组件类型
const Emails = {
  [TemplateName.EXAMPLE_TEMPLATE]: {
    html: TestTemplate,
    subject: "This is a test",
    // 其余配置
  }
  // 其他模板配置
} satisfies Record<TemplateName, EmailConfig>

// 可从Emails反推精确的EmailMapping类型
type EmailMapping = typeof Emails

2. 修正sendEmail泛型定义

async function sendEmail<T extends TemplateName>(
  template: T,
  opts: ComponentProps<EmailMapping[T]['html']>
) {
  // 原有实现逻辑
}

低版本TS兼容方案(无satisfies)

如果TS版本低于4.9,可通过泛型工具函数约束结构:

function defineEmails<T extends Record<TemplateName, EmailConfig>>(config: T) {
  return config
}

const Emails = defineEmails({
  [TemplateName.EXAMPLE_TEMPLATE]: {
    html: TestTemplate,
    subject: "This is a test",
  }
})

修正后调用sendEmail时,第二个参数会自动推导为对应模板的Props类型,可正确校验所有字段。

内容的提问来源于stack exchange,提问作者James Black

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:36:02