Настройка TypeScript
React Native поддерживает TypeScript из коробки. При создании нового проекта выберите TypeScript-шаблон.
1npx react-native init MyApp --template react-native-template-typescript
▸tsconfig.json
1{2 "compilerOptions": {3 "target": "esnext",4 "module": "commonjs",5 "lib": ["es2019"],6 "allowJs": true,7 "jsx": "react-native",8 "noEmit": true,9 "strict": true,10 "moduleResolution": "node",11 "resolveJsonModule": true,12 "isolatedModules": true,13 "esModuleInterop": true,14 "skipLibCheck": true,15 "noUnusedLocals": true,16 "noUnusedParameters": true,17 "baseUrl": ".",18 "paths": {19 "@/*": ["src/*"]20 }21 },22 "include": ["src/**/*", "**/*.ts", "**/*.tsx"],23 "exclude": ["node_modules", "babel.config.js", "metro.config.js"]24}
Типизация компонентов
▸Props с типами
1interface UserCardProps {2 name: string;3 email: string;4 avatar?: string;5 role: 'admin' | 'user' | 'guest';6 onEdit: (userId: string) => void;7 children?: React.ReactNode;8}910function UserCard({ name, email, avatar, role, onEdit, children }: UserCardProps) {11 return (12 <View style={styles.card}>13 {avatar && <Image source={{ uri: avatar }} style={styles.avatar} />}14 <Text style={styles.name}>{name}</Text>15 <Text style={styles.email}>{email}</Text>16 <Text style={styles.role}>{role}</Text>17 <Button title="Edit" onPress={() => onEdit(email)} />18 {children}19 </View>20 );21}
▸Props с Generic
1interface ListProps<T> {2 items: T[];3 renderItem: (item: T) => React.ReactElement;4 keyExtractor: (item: T) => string;5}67function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {8 return (9 <FlatList10 data={items}11 keyExtractor={keyExtractor}12 renderItem={({ item }) => renderItem(item)}13 />14 );15}
Типизация навигации
1import { NativeStackNavigationProp } from '@react-navigation/native-stack';23type RootStackParamList = {4 Home: undefined;5 Profile: { userId: string };6 Settings: { section?: string };7};89type NavigationProp = NativeStackNavigationProp<RootStackParamList>;1011interface Props {12 navigation: NavigationProp;13}1415function HomeScreen({ navigation }: Props) {16 return (17 <Button18 title="Go to Profile"19 onPress={() => navigation.navigate('Profile', { userId: '123' })}20 />21 );22}
Типизация хуков
▸useState
1interface User {2 id: string;3 name: string;4 email: string;5}67const [user, setUser] = useState<User | null>(null);8const [isLoading, setIsLoading] = useState<boolean>(true);9const [error, setError] = useState<string | null>(null);
▸useRef
1const inputRef = useRef<TextInput>(null);2const timerRef = useRef<NodeJS.Timeout | null>(null);
Типизация нативных модулей
1interface NativeBridge {2 getBatteryLevel(): Promise<number>;3 getDeviceInfo(): Promise<{4 model: string;5 systemVersion: string;6 }>;7}89const { NativeModules } = require('react-native');10const Bridge: NativeBridge = NativeModules.BatteryModule;
Обработка ошибок
1class AppError extends Error {2 constructor(3 message: string,4 public code: string,5 public statusCode?: number6 ) {7 super(message);8 this.name = 'AppError';9 }10}1112function handleApiError(error: unknown): string {13 if (error instanceof AppError) {14 return error.message;15 }16 if (error instanceof Error) {17 return error.message;18 }19 return 'Неизвестная ошибка';20}
Утилиты типов
1// Опциональные свойства2type Partial<T> = { [P in keyof T]?: T[P] };34// Только определённые свойства5type Pick<T, K extends keyof T> = { [P in K]: T[P] };67// Исключение свойств8type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;910// Union типы11type Status = 'idle' | 'loading' | 'success' | 'error';
Заключение
TypeScript в React Native повышает качество кода, упрощает рефакторинг и помогает ловить ошибки на этапе компиляции. Правильная типизация пропсов, навигации и нативных модулей делает код надёжнее и проще для поддержки.