1. Tại sao cần chia sẻ kiểu? Khi phát triển song song web và mobile, việc duy trì hai bộ kiểu riêng biệt dễ dẫn đến sự không nhất quán: tên trường API thay đổi mà chỉ cập nhật một phía, component dùng sai props, hay lỗi runtime chỉ phát hiện khi chạy. Một thư viện kiểu chung (shared/types) giúp compiler bắt lỗi sớm, giảm thời gian review và tăng độ tin cậy khi refactor. 2. Cấu trúc monorepo gợi ý - apps/web (Next.js) - apps/mobile (Expo) - packages/shared-types – chứa interface, enum, type guard - packages/shared-utils – hàm helper thuần TypeScript (date format, validation, storage abstraction) - packages/ui – design system component (nếu đã có) Mỗi package có package.json riêng, tsconfig.json extends từ root tsconfig.base.json. 3. Ví dụ thực tế: shared/types ```ts // packages/shared-types/src/api.ts export interface User { id: string; name: string; email: string; avatarUrl?: string; } export type AuthResponse = { user: User; accessToken: string; refreshToken: string }; ``` Trong web: `import { User, AuthResponse } from '@myorg/shared-types';` Trong mobile: cùng import, không cần copy paste. 4. Cấu hình tsconfig path mapping Trong root `tsconfig.base.json`: ```json { "compilerOptions": { "baseUrl": ".", "paths": { "@myorg/shared-types": ["packages/shared-types/src"], "@myorg/shared-utils": ["packages/shared-utils/src"] } } } ``` Mỗi app extends base và bật `"composite": true` để TypeScript hiểu project references. 5. Lưu ý khi dùng API nền tảng riêng - `window`, `localStorage` chỉ có trên web → bọc trong `shared-utils/platform.ts` với conditional export. - React Native không hỗ trợ `fetch` polyfill mặc định → cung cấp `apiClient` dùng `axios` hoặc `ky` với adapter tùy biến. - Tránh import side‑effect (ví dụ CSS) trong shared package; chỉ chứa logic thuần TS. 6. Mẹo áp dụng ngay - Thêm script `typecheck` ở root chạy `tsc --build` để kiểm tra toàn bộ monorepo một lần. - Dùng `eslint-plugin-import` với `settings.import.resolver.typescript` để autocomplete đường dẫn `@myorg/...`. - Viết unit test cho shared-utils (Jest) và chạy trong CI của cả hai app. - Khi nâng cấp React/Next/Expo, chỉ cần bump version ở root `package.json` và chạy `yarn install` – các package con tự động nhận bản cập nhật. Kết luận: đầu tư sớm cho shared types và utilities giúp hai nền tảng nói chung một ngôn ngữ, giảm bug lặp lại và tăng tốc độ phát triển feature mới.