如何在React+TypeScript中分离类型声明与组件实现?
完全可以实现这种纯类型SDK的方案
这和C语言的头文件动态链接思路完全一致——SDK只提供类型契约,运行时由宿主环境提供具体实现。下面是具体的实现步骤:
1. 搭建纯类型的SDK库
首先创建一个只导出TypeScript类型的npm包:
- 初始化npm项目,配置
package.json,重点指定类型入口,同时避免运行时引入空实现:{ "name": "sdk", "version": "1.0.0", "types": "./dist/index.d.ts", "main": "./dist/empty.js", // 指向空文件防止运行时报错 "scripts": { "build": "tsc" }, "devDependencies": { "typescript": "^5.0.0", "@types/react": "^18.0.0" }, "peerDependencies": { "react": "^18.0.0" } } - 配置
tsconfig.json,让TypeScript只生成类型声明文件:{ "compilerOptions": { "target": "ESNext", "module": "ESNext", "declaration": true, "emitDeclarationOnly": true, "outDir": "./dist", "jsx": "react-jsx", "strict": true, "moduleResolution": "NodeNext" }, "include": ["src/**/*"] } - 编写类型声明文件
src/index.d.ts,定义组件的类型契约:import type { FC } from 'react'; export interface VideoProps { src: string; // 按需添加其他props的类型定义 } // 声明Video是符合Props类型的React组件 export const Video: FC<VideoProps>; - 执行
npm run build生成dist目录下的类型文件,然后发布这个包到npm(或私有仓库)。
2. 在业务仓库中使用SDK
安装SDK后,直接像普通组件一样导入使用,TypeScript会自动识别类型:
import { Video } from "sdk"; export default function MyComponent() { return ( <Video src="https://example.com/video.mp4" /> ); }
此时TypeScript会基于SDK的类型声明做语法检查,确保你传的props符合要求,但不会涉及任何运行时代码。
3. 用remote-component注入运行时实现
在宿主应用中,通过remote-component的配置把SDK的Video映射到实际的组件实现:
import MyVideo from "../my-video"; import { createRequires, createRemoteComponent } from 'remote-component'; const resolve = { sdk: { Video: MyVideo, }, }; const requires = createRequires(resolve); export const RemoteComponent = createRemoteComponent({ requires });
当RemoteComponent加载你的MyComponent时,会自动替换所有来自sdk的导入,把Video换成MyVideo的实际实现,运行时就能正常渲染组件。
关键注意事项
- SDK必须无运行时代码:所有导出都得是TypeScript类型,不能有任何实际的组件逻辑,否则业务仓库运行时会因找不到实现报错。
- 类型与实现要匹配:宿主环境提供的
MyVideo组件必须完全符合SDK定义的VideoProps类型,避免运行时出现不兼容问题。 - 声明peer依赖:SDK的
package.json里要声明React为peer依赖,确保宿主环境的React版本和SDK兼容。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

