☰
TypeScript与React/Vue框架深度整合实战指南
2026/10/8 12:25:37 网站建设 项目流程

1. TypeScript与主流框架结合的核心价值

TypeScript作为JavaScript的超集,近年来在前端开发领域获得了广泛认可。根据2023年开发者调查报告,超过78%的前端开发者表示在项目中使用TypeScript,其中与React、Vue等框架的结合是最常见的应用场景。这种结合不是简单的技术堆砌,而是为了解决现代前端开发中的几个关键痛点:

  • 类型安全:JavaScript的动态类型特性在大型项目中容易引发运行时错误,TypeScript的静态类型检查可以在编译阶段捕获大部分类型相关错误
  • 代码可维护性:随着项目规模增长,明确的接口定义和类型约束使代码更易于理解和维护
  • 开发体验提升:现代IDE(如VSCode)对TypeScript提供了出色的智能提示和重构支持
  • 框架生态适配:主流前端框架(React、Vue、Angular)都已提供对TypeScript的一等公民支持

在实际项目中,我观察到采用TypeScript的团队在长期维护成本和迭代效率上通常有显著优势。特别是在多人协作的中大型项目中,类型系统就像一份活的文档,极大降低了沟通成本。

2. TypeScript与React的深度整合

2.1 基础类型定义

React与TypeScript的结合已经非常成熟,最新的React 18版本更是内置了完善的TypeScript支持。以下是创建类型化React组件的基础模式:

interface UserProfileProps { name: string; age: number; isPremium?: boolean; // 可选属性 onUpdate: (newName: string) => void; // 回调函数类型 } const UserProfile: React.FC<UserProfileProps> = ({ name, age, isPremium = false, onUpdate }) => { // 组件实现... }

注意:虽然React.FC泛型类型很方便,但在实际项目中,我建议直接使用普通函数定义组件。因为React.FC会隐式包含children属性,可能导致意外的类型行为。

2.2 Hooks的类型化使用

React Hooks与TypeScript的结合需要特别注意类型推断:

const [count, setCount] = useState<number>(0); // 显式类型声明 const [user, setUser] = useState<User | null>(null); // 联合类型 useEffect(() => { const fetchData = async () => { const response = await fetch('/api/user'); const data: User = await response.json(); setUser(data); }; fetchData(); }, []);

对于自定义Hook,正确的类型定义可以极大提升复用性:

function useLocalStorage<T>(key: string, initialValue: T) { const [value, setValue] = useState<T>(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initialValue; }); useEffect(() => { localStorage.setItem(key, JSON.stringify(value)); }, [key, value]); return [value, setValue] as const; // 使用as const固定元组类型 }

2.3 高级模式与性能优化

在大型React+TypeScript项目中,这些模式特别有用:

  1. 类型化Context:
interface ThemeContextType { mode: 'light' | 'dark'; toggle: () => void; } const ThemeContext = createContext<ThemeContextType | undefined>(undefined); // 自定义Hook确保使用时上下文存在 function useTheme() { const context = useContext(ThemeContext); if (!context) { throw new Error('useTheme必须在ThemeProvider内使用'); } return context; }
  1. 高阶组件类型:
function withAuth<P extends object>(Component: React.ComponentType<P>) { return function Authenticated(props: P) { const [isAuthenticated] = useAuth(); return isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />; } }
  1. 性能优化技巧:
  • 使用React.memo时配合类型参数:
const MemoizedComponent = React.memo<ComponentProps>( Component, (prev, next) => prev.id === next.id );
  • 对于大型数据列表,使用useMemo和正确的类型标注:
const sortedUsers = useMemo<User[]>( () => users.sort((a, b) => a.name.localeCompare(b.name)), [users] );

3. TypeScript与Vue 3的组合式API实践

3.1 组合式API基础类型

Vue 3的组合式API与TypeScript是天作之合。使用<script setup>语法时,类型支持尤为出色:

<script setup lang="ts"> import { ref, computed } from 'vue'; interface User { id: number; name: string; email: string; } // 响应式数据 const count = ref<number>(0); // 显式类型 const users = ref<User[]>([]); // 复杂对象数组 // 计算属性 const userCount = computed<number>(() => users.value.length); // 函数 const addUser = (user: User) => { users.value.push(user); }; </script>

实操心得:在Vue单文件组件中,我习惯将接口定义放在单独的types文件夹中集中管理,特别是当多个组件共享相同类型时。

3.2 组件Props的类型定义

Vue 3提供了多种定义Props类型的方式,每种适合不同场景:

  1. 运行时声明(兼容选项式API):
<script setup lang="ts"> const props = defineProps({ title: { type: String, required: true }, count: { type: Number, default: 0 } }); </script>
  1. 纯类型声明(推荐方式):
<script setup lang="ts"> interface Props { title: string; count?: number; } const props = defineProps<Props>(); </script>
  1. 带默认值的类型声明:
<script setup lang="ts"> interface Props { title: string; count?: number; } const props = withDefaults(defineProps<Props>(), { count: 0 }); </script>

3.3 组合式函数的高级模式

开发类型安全的组合式函数是Vue+TypeScript的核心优势:

// useFetch.ts import { ref } from 'vue'; interface UseFetchOptions<T> { immediate?: boolean; initialData?: T; } export function useFetch<T>(url: string, options: UseFetchOptions<T> = {}) { const data = ref<T | undefined>(options.initialData); const error = ref<Error | null>(null); const loading = ref(false); const execute = async () => { try { loading.value = true; const response = await fetch(url); data.value = await response.json() as T; } catch (err) { error.value = err as Error; } finally { loading.value = false; } }; if (options.immediate) { execute(); } return { data, error, loading, execute }; }

使用时获得完整的类型推断:

const { data: user } = useFetch<User>('/api/user', { immediate: true }); // user的类型自动推断为Ref<User | undefined>

4. 常见问题与解决方案

4.1 类型定义冲突问题

在整合第三方库时,经常会遇到类型定义不完整或冲突的情况。以下是几种处理方案:

  1. 模块扩展(增强类型定义):
// types/vue.d.ts declare module 'vue' { interface ComponentCustomProperties { $filters: { formatDate: (date: Date) => string; }; } }
  1. 类型断言(谨慎使用):
const element = document.getElementById('app') as HTMLElement; // 或者 const user = response.data as unknown as User;
  1. 类型守卫(更安全的运行时检查):
function isUser(data: unknown): data is User { return typeof data === 'object' && data !== null && 'name' in data && 'email' in data; } if (isUser(apiResponse)) { // 在此块中apiResponse被推断为User类型 }

4.2 性能优化类型技巧

  1. 精确的类型导入:
// 而不是 import { SomeType } from 'some-library'; import type { SomeType } from 'some-library';
  1. 条件类型与工具类型:
type ApiResponse<T> = { data: T; error: null; } | { data: null; error: string; }; function handleResponse<T>(response: ApiResponse<T>) { if (response.error) { console.error(response.error); return; } // 这里response.data自动推断为T类型 processData(response.data); }
  1. 避免过度类型断言:
// 不推荐 const user = {} as User; // 推荐 const user: Partial<User> = {};

4.3 项目结构最佳实践

在中大型项目中,我推荐以下类型组织方式:

src/ types/ global.d.ts # 全局类型声明 api/ # API相关类型 user.ts product.ts components/ # 组件Props类型 Button.ts Modal.ts utils/ type-guards.ts # 类型守卫函数

对于共享类型,可以使用index.ts进行统一导出:

// types/api/index.ts export * from './user'; export * from './product';

5. 框架特定工具与配置

5.1 React项目配置要点

  1. tsconfig.json关键配置:
{ "compilerOptions": { "jsx": "react-jsx", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "node", "baseUrl": "./src", "paths": { "@/*": ["./*"] } }, "include": ["src"] }
  1. 推荐VSCode插件:
  • ESLint
  • Prettier
  • TypeScript Importer
  • React Refactor

5.2 Vue项目配置优化

  1. vite.config.ts关键配置:
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': '/src', }, }, server: { port: 3000, }, });
  1. Volar扩展配置: 在VSCode设置中添加:
{ "volar.takeOverMode.enabled": true, "volar.experimental.templateInterpolationService": true }

5.3 共享配置方案

对于全栈项目或微前端架构,可以创建共享类型包:

  1. 创建shared-types包:
shared-types/ src/ index.ts package.json tsconfig.json
  1. 使用项目引用:
// tsconfig.json { "references": [ { "path": "../shared-types" } ] }
  1. 消费共享类型:
import { User } from 'shared-types';

6. 测试与类型安全

6.1 类型化测试实践

使用Jest与TypeScript结合时,这些模式很有帮助:

describe('UserService', () => { let service: UserService; beforeEach(() => { service = new UserService(); }); it('should create user with valid data', async () => { const userData: CreateUserDto = { name: 'John', email: 'john@example.com' }; const result = await service.create(userData); expect(result).toMatchObject<User>({ id: expect.any(String), ...userData }); }); });

6.2 契约测试与类型

使用Swagger或GraphQL生成类型定义:

// 使用swagger-typescript-api生成 import { User } from './generated/api'; // 或者使用graphql-codegen const GET_USER = gql` query GetUser($id: ID!) { user(id: $id) { id name email } } `; type GetUserQuery = { user: Pick<User, 'id' | 'name' | 'email'>; };

6.3 类型覆盖率检查

安装type-coverage工具检查类型覆盖率:

npx type-coverage

在CI中添加检查:

- name: Check Type Coverage run: | npx type-coverage if [ $? -ne 0 ]; then echo "Type coverage check failed" exit 1 fi

7. 迁移策略与渐进式采用

7.1 从JavaScript迁移

  1. 渐进式迁移步骤:
  • 将文件重命名为.tsx/.ts
  • 添加基本tsconfig.json
  • 逐步添加类型注解
  • 启用更严格的检查选项
  1. 迁移工具:
# 自动添加JSDoc类型注释 npx typescript-jsdoc-comments src/**/*.js --write

7.2 从Flow迁移

  1. 使用flow-to-ts转换工具:
npx flow-to-ts src/**/*.js --write --delete-source
  1. 处理主要差异:
  • 将$ReadOnlyArray改为ReadonlyArray
  • 将$Exact改为精确类型{| ... |}

7.3 混合代码库管理

在过渡期间,可以使用这些配置:

// tsconfig.json { "compilerOptions": { "allowJs": true, "checkJs": true } }

添加// @ts-check注释到JS文件顶部,获得基本类型检查:

// @ts-check /** * @typedef {Object} User * @property {string} name * @property {number} age */ /** * @param {User} user */ function greet(user) { return `Hello, ${user.name}`; }

8. 高级类型模式与框架集成

8.1 条件类型与框架API

利用TypeScript高级类型增强框架API:

// 基于props动态推断emits类型 type EmitsFromProps<T> = T extends { onClick: (arg: infer A) => void } ? { (e: 'click', arg: A): void } : {}; function defineComponent<T extends {}>( props: T, setup: (props: T, emit: EmitsFromProps<T>) => void ) { // 实现... }

8.2 类型安全的依赖注入

实现类型安全的DI容器:

class Container { private services = new Map<symbol, unknown>(); register<T>(key: string, service: T): void { const symbol = Symbol.for(key); this.services.set(symbol, service); } resolve<T>(key: string): T { const symbol = Symbol.for(key); const service = this.services.get(symbol); if (!service) { throw new Error(`Service ${key} not found`); } return service as T; } } // 使用 const container = new Container(); container.register<UserService>('userService', new UserService()); const userService = container.resolve<UserService>('userService');

8.3 元编程与类型推导

利用模板字符串类型实现高级模式:

type RouteParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}` ? { [K in Param | keyof RouteParams<Rest>]: string } : T extends `${string}:${infer Param}` ? { [K in Param]: string } : {}; function createRoute<T extends string>(path: T) { return { path, build: (params: RouteParams<T>) => path.replace(/:(\w+)/g, (_, key) => params[key as keyof RouteParams<T>]) }; } const userRoute = createRoute('/users/:userId/posts/:postId'); // userRoute.build的参数类型自动推断为 { userId: string; postId: string }

9. 状态管理的类型安全实践

9.1 Redux Toolkit类型化配置

import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit'; interface UserState { name: string; email: string; status: 'idle' | 'loading' | 'succeeded' | 'failed'; } const initialState: UserState = { name: '', email: '', status: 'idle' }; const userSlice = createSlice({ name: 'user', initialState, reducers: { setUser(state, action: PayloadAction<Pick<UserState, 'name' | 'email'>>) { state.name = action.payload.name; state.email = action.payload.email; }, setStatus(state, action: PayloadAction<UserState['status']>) { state.status = action.payload; } } }); export const { setUser, setStatus } = userSlice.actions; export const store = configureStore({ reducer: { user: userSlice.reducer } }); // 推导RootState和AppDispatch类型 export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch;

9.2 Pinia的类型安全Store

import { defineStore } from 'pinia'; interface User { id: string; name: string; email: string; } interface UserState { currentUser: User | null; users: User[]; } export const useUserStore = defineStore('user', { state: (): UserState => ({ currentUser: null, users: [] }), actions: { async fetchUsers() { const response = await fetch('/api/users'); const users: User[] = await response.json(); this.users = users; }, setUser(user: User) { this.currentUser = user; } }, getters: { activeUsers: (state) => state.users.filter(user => !user.deactivated), getUserById: (state) => (id: string) => state.users.find(user => user.id === id) } });

9.3 状态机与类型安全

使用XState实现类型化状态机:

import { createMachine, assign } from 'xstate'; interface UserContext { user: User | null; error: string | null; } type UserEvent = | { type: 'FETCH' } | { type: 'RESOLVE'; user: User } | { type: 'REJECT'; error: string }; const userMachine = createMachine<UserContext, UserEvent>({ id: 'user', initial: 'idle', context: { user: null, error: null }, states: { idle: { on: { FETCH: 'loading' } }, loading: { invoke: { src: 'fetchUser', onDone: { target: 'success', actions: 'setUser' }, onError: { target: 'failure', actions: 'setError' } } }, success: { entry: 'notifySuccess' }, failure: { on: { FETCH: 'loading' } } } }, { actions: { setUser: assign({ user: (_, event) => event.data }), setError: assign({ error: (_, event) => event.data }) } });

10. 性能与调试技巧

10.1 类型性能优化

  1. 避免过度使用枚举:
// 不推荐 enum Status { Active = 'active', Inactive = 'inactive' } // 推荐 type Status = 'active' | 'inactive';
  1. 使用Branded类型替代运行时检查:
type Email = string & { readonly __brand: unique symbol }; function createEmail(value: string): Email { if (!value.includes('@')) { throw new Error('Invalid email'); } return value as Email; } function sendEmail(email: Email) { // ... }

10.2 调试类型问题

  1. 类型展开技巧:
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never; // 调试复杂类型 type DebugType = Expand<SomeComplexType>;
  1. 类型断点调试:
// 在复杂泛型中插入调试点 type MyComplexType<T> = // @ts-expect-error - 查看中间类型 T extends SomeCondition ? TrueBranch : FalseBranch;

10.3 性能监控与分析

  1. 编译时间监控:
tsc --extendedDiagnostics
  1. 使用tsc --generateTrace生成编译跟踪:
tsc --generateTrace traceDir
  1. 关键指标关注:
  • 类型检查时间
  • 内存使用量
  • 项目引用构建顺序

11. 未来趋势与演进方向

11.1 TypeScript 5.0+新特性应用

  1. 装饰器标准支持:
@logged class UserService { @bound getUser(@validate id: string) { // ... } }
  1. satisfies操作符:
const config = { port: 3000, host: 'localhost' } satisfies ServerConfig;
  1. 模板字符串类型增强:
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; type ApiPath = `/${string}`; type Endpoint = `${HttpMethod} ${ApiPath}`; function handleRequest(endpoint: Endpoint) { // ... } handleRequest('GET /users'); // 合法 handleRequest('PATCH /posts'); // 错误

11.2 框架官方类型演进

  1. React Server Components类型支持:
async function UserList() { const users = await fetchUsers(); return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
  1. Vue Reactivity Transform类型:
<script setup lang="ts"> const count = $ref(0); // 自动推断为number const user = $ref<User>({ name: '' }); // 显式类型 </script>

11.3 全栈类型安全趋势

  1. tRPC类型共享:
// 后端 const router = t.router({ getUser: t.procedure .input(z.object({ id: z.string() })) .query(({ input }) => { return db.user.findUnique({ where: { id: input.id } }); }), }); // 前端自动获得类型安全API调用 const user = await trpc.getUser.query({ id: '123' });
  1. Prisma类型推导:
const user = await prisma.user.findUnique({ where: { id: '123' }, select: { name: true, email: true } }); // user类型自动推断为 { name: string; email: string } | null
  1. OpenAPI类型生成:
npx openapi-typescript https://api.example.com/openapi.json -o src/types/api.ts

12. 实战案例:构建类型安全的全栈应用

12.1 项目架构设计

fullstack-app/ packages/ client/ # React+TypeScript前端 server/ # Node.js+TypeScript后端 shared/ # 共享类型定义 package.json # 使用workspaces

12.2 共享类型定义

// shared/src/types/user.ts export interface User { id: string; name: string; email: string; createdAt: Date; } export type CreateUserDto = Pick<User, 'name' | 'email'>; export type UpdateUserDto = Partial<CreateUserDto>;

12.3 前后端类型集成

  1. 前端API客户端:
// client/src/api/client.ts import type { User, CreateUserDto, UpdateUserDto } from 'shared'; export async function fetchUsers(): Promise<User[]> { const response = await fetch('/api/users'); return response.json(); } export async function createUser(dto: CreateUserDto): Promise<User> { const response = await fetch('/api/users', { method: 'POST', body: JSON.stringify(dto) }); return response.json(); }
  1. 后端路由处理:
// server/src/routes/users.ts import type { User, CreateUserDto } from 'shared'; import { Router } from 'express'; const router = Router(); router.get<{}, User[], {}>('/', async (req, res) => { const users = await prisma.user.findMany(); res.json(users); }); router.post<{}, User, CreateUserDto>('/', async (req, res) => { const user = await prisma.user.create({ data: req.body }); res.status(201).json(user); });

12.4 构建与部署配置

  1. 共享包的tsconfig:
{ "compilerOptions": { "composite": true, "declaration": true, "declarationMap": true, "rootDir": "src", "outDir": "dist" }, "include": ["src"] }
  1. 项目引用配置:
// client/tsconfig.json { "references": [{ "path": "../shared" }] }
  1. 类型检查CI流水线:
- name: Check Types run: | cd client && npm run type-check cd ../server && npm run type-check

13. 资源推荐与学习路径

13.1 官方资源

  1. TypeScript官方文档:
  • TypeScript Handbook
  • TypeScript Release Notes
  1. 框架官方指南:
  • React TypeScript Cheatsheet
  • Vue with TypeScript

13.2 进阶学习

  1. 高级类型专题:
  • TypeScript类型体操
  • TypeScript Deep Dive
  1. 性能优化:
  • TypeScript Performance
  • Project References指南

13.3 工具链推荐

  1. 代码生成:
  • graphql-code-generator
  • swagger-typescript-api
  1. 代码质量:
  • TypeStat - 自动类型迁移工具
  • ts-prune - 查找未使用的导出
  1. 可视化工具:
  • ts-ast-viewer - 探索TypeScript AST
  • TypeScript Playground - 在线实验环境

14. 持续集成与自动化

14.1 类型检查CI配置

name: Type Check on: [push, pull_request] jobs: type-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 18 - run: npm ci - run: npm run type-check

14.2 自动化类型测试

使用dtslint测试类型定义:

{ "scripts": { "test:types": "dtslint types" } }

14.3 变更影响分析

# 获取类型检查影响的文件列表 tsc --extendedDiagnostics --noEmit --listFilesOnly > affectedFiles.txt

15. 团队协作规范

15.1 代码评审要点

  1. 类型设计评审清单:
  • 是否过度使用any或类型断言
  • 复杂类型是否适当分解
  • 接口设计是否符合SOLID原则
  • 类型是否真实反映了运行时行为
  1. 常见反模式标记:
// 反模式:无意义的泛型 function identity<T>(value: T): T { return value; } // 改进:直接使用具体类型 function identity(value: string): string { return value; }

15.2 文档规范

  1. 类型文档标准:
/** * 表示系统用户实体 * @property id - 用户唯一标识 * @property name - 用户显示名称 * @property email - 用户联系邮箱 * @property createdAt - 账户创建时间 */ interface User { id: string; name: string; email: string; createdAt: Date; }
  1. 变更日志要求:
## [1.2.0] - 2023-07-15 ### Changed - `User`接口新增`avatarUrl`可选属性 - `createUser`现在接受`UserPreferences`参数

15.3 知识共享机制

  1. 类型研讨会:
  • 每月分享复杂类型解决方案
  • 评审社区类型定义贡献
  • 探索新TypeScript特性
  1. 内部类型库:
  • 维护常用工具类型集合
  • 共享领域特定类型定义
  • 提供类型迁移指南

16. 疑难问题深度解析

16.1 循环类型依赖

解决方案1:使用接口合并

// types/user.ts interface User { posts: Post[]; } // types/post.ts interface Post { author: User; }

解决方案2:类型前置声明

// types/models.ts export type { User } from './user'; export type { Post } from './post'; // user.ts import type { Post } from './models'; export interface User { posts: Post[]; } // post.ts import type { User } from './models'; export interface Post { author: User; }

16.2 高阶组件类型推断

function withLogging<P extends {}>( Component: React.ComponentType<P> ): React.FC<P & { logLevel?: 'debug' | 'info' }> { return function LoggedComponent(props) { console.log(`[${props.logLevel || 'info'}] Rendering`); return <Component {...props} />; }; } // 使用 const EnhancedButton = withLogging(Button); <EnhancedButton logLevel="debug" onClick={...} />;

16.3 动态属性访问类型

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const user = { name: 'John', age: 30 }; const name = getProperty(user, 'name'); // string const age = getProperty(user, 'age'); // number

17. 性能关键型应用优化

17.1 避免类型实例化深度

// 不推荐:深层嵌套实例化 type DeepNested<T> = { level1: { level2: { level3: T } } }; // 推荐:扁平结构 type FlatStructure<T> = { level1: T; level2: T; level3: T; };

17.2 条件类型优化

// 优化前 type MyType<T> = T extends string ? StringType : T extends number ? NumberType : DefaultType; // 优化后 type MyType<T> = [T] extends [string] ? StringType : [T] extends [number] ? NumberType : DefaultType;

17.3 类型缓存策略

// 使用接口合并缓存中间类型 interface TypeCache { User: { id: string; name: string; }; Product: { id: string; price: number; }; } function getFromCache<K extends keyof TypeCache>(key: K): TypeCache[K] { // ... }

18. 类型安全与运行时验证

18.1 Zod模式验证

import { z } from 'zod'; const UserSchema = z.object({ id: z.string().uuid(), name: z.string().min(2), email: z.string().email(), age: z.number().int().positive().optional() }); type User = z.infer<typeof UserSchema>; function createUser(input: unknown) { const user = UserSchema.parse(input); // user被推断为User类型 }

18.2 类型守卫工厂

function createTypeGuard<T>(schema: z.ZodType<T>) { return (value: unknown): value is T => { return schema.safeParse(value).success; }; } const isUser = createTypeGuard(UserSchema); if (isUser(apiResponse)) { // apiResponse被推断为User类型 }

18.3 序列化类型安全

class SafeSerializer { private static reviver(key: string, value: unknown) { if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}/.test(value)) { return new Date(value); } return value; } static parse<T>(json: string): T { return JSON.parse(json, this.reviver) as T; } static stringify(value: unknown): string { return JSON.stringify(value); } } const user = SafeSerializer.parse<User>(localStorage.getItem('user')!);

19. 微前端架构中的类型共享

19.1 模块联邦类型

// host-app/src/types/remote.d.ts declare module 'remote-app/components' { export const Button: React.FC<{ variant?: 'primary' | 'secondary'; onClick?: () => void; }>; export const Header: React.FC<{ title: string; logo?: string; }>; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询