Typescript泛型函数如何根据模板枚举推导对应React组件Props类型
问题根源
你当前的类型定义把每个模板对应的具体组件类型抹除了:
- 原
EmailMapping定义语法错误且类型过宽,所有key对应的html字段都被推导为通用的React.ComponentType,TS无法关联到具体的组件Props 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
相关产品推荐
相关产品推荐

