如何让TypeScript动态渲染React组件时自动推断返回值类型
解决React动态弹窗组件的类型推断问题
核心问题分析
原代码中Opendialog的泛型约束写法错误,R未被声明为泛型参数,导致TypeScript无法关联弹窗组件props的泛型与Promise返回值类型,进而无法自动推断result的类型。
修正方案
调整OpenDialog的类型定义,让TypeScript能从弹窗组件的props类型中自动推导返回值类型R,同时优化props传递逻辑避免重复定义onClose。
完整修正代码
import { FunctionComponent, createElement, render, unmountComponentAtNode } from 'react'; // 基础弹窗props类型,泛型R代表关闭时返回的结果类型 type InvocableDialogProps<R = never> = { open: boolean; onClose: (r: R) => void; }; // 修正后的弹窗调用函数类型: // 泛型R自动从传入的Dialog组件props中推导,props参数排除onClose(由函数内部注入) type OpenDialog = <R>( Dialog: FunctionComponent<InvocableDialogProps<R>>, props: Omit<InvocableDialogProps<R>, 'onClose'> ) => Promise<R>; const openDialog: OpenDialog = (Dialog, props) => { return new Promise(resolve => { // 创建临时DOM容器用于渲染弹窗 const container = document.createElement('div'); document.body.appendChild(container); // 渲染弹窗并注入onClose回调以resolve Promise render( createElement(Dialog, { ...props, open: true, onClose: (result) => { resolve(result); // 弹窗关闭后卸载组件并清理DOM unmountComponentAtNode(container); document.body.removeChild(container); }, }), container ); }); }; // 示例弹窗组件:返回值类型为boolean type DialogProps = InvocableDialogProps<boolean>; const Dialog: FunctionComponent<DialogProps> = ({ onClose }) => { return ( <div style={{ padding: '20px', border: '1px solid #ccc' }}> <button onClick={() => onClose(true)}>确认</button> <button onClick={() => onClose(false)} style={{ marginLeft: '10px' }}>取消</button> </div> ); }; // 使用示例:result自动推断为boolean类型 async function triggerDialog() { const result = await openDialog(Dialog, {}); // 此处result类型为boolean,可直接使用 console.log('弹窗返回结果:', result); }
关键说明
- 泛型推导:将
OpenDialog定义为泛型函数,TypeScript会根据传入的Dialog组件的InvocableDialogProps<R>泛型参数,自动推断出Promise的返回值类型R。 - Props优化:使用
Omit<InvocableDialogProps<R>, 'onClose'>确保调用时无需传入onClose,避免与函数内部注入的回调冲突。 - DOM管理:补充了弹窗的渲染与卸载逻辑,确保组件正确挂载到DOM,关闭后清理资源。
内容的提问来源于stack exchange,提问作者Gustavo Perez Machado
相关产品推荐
相关产品推荐

