React Native dan TypeScript di 2026: Arsitektur Type-Safe dan Pertanyaan Wawancara
Bangun aplikasi React Native type-safe dengan TypeScript, Codegen, TurboModules, dan Strict TypeScript API. Mencakup pola arsitektur, typed navigation, persyaratan toolchain 0.87, dan pertanyaan wawancara.

React Native TypeScript type safety mengalami pematangan signifikan hingga pertengahan 2026, dengan versi 0.87 menjadikan Strict TypeScript API sebagai default wajib dan menyelesaikan modernisasi toolchain secara menyeluruh. TypeScript bukan lagi pelengkap opsional antara JavaScript dan kode native: TypeScript kini mengendalikan seluruh kontrak dari component props hingga interface TurboModule, menangkap ketidakcocokan tipe pada saat build alih-alih muncul di crash logs produksi.
React Native 0.87 (Agustus 2026) menjadikan Strict TypeScript API sebagai default wajib. Versi ini juga menaikkan persyaratan minimum ke Node.js 22.13+, Kotlin 2.0+, dan Android Gradle Plugin 9. Opsi opt-out untuk legacy deep imports tetap tersedia hingga 0.88 saja.
Mengapa TypeScript Kini Menjadi Default untuk Proyek React Native
Sejak versi 0.76, setiap perintah npx react-native init menghasilkan scaffolding proyek TypeScript. Namun perubahan sesungguhnya terjadi pada batas native. Sebelum Codegen, developer menulis type assertions manual ketika data berpindah dari JavaScript ke Objective-C atau Kotlin, sebuah kontrak stringly-typed yang gagal secara diam-diam saat runtime. Codegen membaca file spesifikasi TypeScript dan menghasilkan interface C++, Objective-C++, serta Java/Kotlin secara otomatis. Jika spesifikasi TypeScript mendeklarasikan method yang mengembalikan number, interface native yang dihasilkan memaksakan constraint tersebut pada saat compile time.
Dokumentasi React Native mencakup setup dasar, namun pola type-safe yang penting dalam produksi lebih mendalam: typed navigation stacks, generic API hooks, discriminated unions untuk state machines, dan TurboModule specs yang digerakkan Codegen.
Strict TypeScript API: Dari Opt-In Menjadi Default
Strict TypeScript API diperkenalkan pada React Native 0.80 sebagai fitur opt-in. Mulai versi 0.87, fitur ini menjadi default wajib untuk semua proyek baru. Types dihasilkan langsung dari source code React Native alih-alih dikelola secara manual, menghilangkan drift antara API yang terdokumentasi dan implementasi aktual.
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
"strict": true,
"exactOptionalPropertyTypes": true,
"noUncheckedIndexedAccess": true
}
}Dengan konfigurasi ini, mengimpor apapun dari subpath seperti react-native/Libraries/Text/Text akan memicu type error. Semua import harus berasal dari root package react-native. Jika library atau codebase lama masih bergantung pada deep imports, tersedia opt-out sementara hingga 0.88:
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
"customConditions": ["react-native", "react-native-legacy-deep-imports"]
}
}Opt-out ini akan dihapus di 0.89. Migrasi sebaiknya dilakukan sebelum waktu tersebut.
Persyaratan Toolchain di 0.87
React Native 0.87 menaikkan versi minimum di seluruh build chain:
| Komponen | Minimum |
|---|---|
| Node.js | 22.13.0 |
| Kotlin | 2.0 (bundled: 2.2.0) |
| Android Gradle Plugin | 9.x |
| Android compileSdk | 34 (min), 37 (target) |
Untuk Android, AGP 9 memerlukan konfigurasi tambahan:
# android/gradle.properties
android.builtInKotlin=false
android.newDsl=falsePersyaratan ini berlaku untuk semua proyek yang menargetkan 0.87+. Panduan migrasi New Architecture mencakup konteks lebih luas dari perubahan ini.
Type-Safe Navigation dengan React Navigation 7
React Navigation 7.x menyediakan dukungan TypeScript first-class. Pola kuncinya: definisikan tipe RootStackParamList yang memetakan setiap nama screen ke params yang diharapkan, kemudian teruskan tipe tersebut ke navigators dan screen components.
export type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
ArticleDetail: { articleId: string; source: 'feed' | 'search' };
};
export type AppTabParamList = {
Dashboard: undefined;
Explore: { category?: string };
Notifications: undefined;
};Screen components kemudian menerima typed props tanpa casting manual:
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import type { RootStackParamList } from '../navigation/types';
type Props = NativeStackScreenProps<RootStackParamList, 'ArticleDetail'>;
export function ArticleDetailScreen({ route, navigation }: Props) {
// route.params.articleId is string, guaranteed by the type
// route.params.source is 'feed' | 'search', no runtime check needed
const { articleId, source } = route.params;
// navigation.navigate('Profile', { userId: '123' }) is type-checked
// navigation.navigate('Profile', {}) causes a compile error: missing userId
return (
<ArticleView id={articleId} referrer={source} />
);
}Pendekatan ini menghilangkan seluruh kategori runtime errors: navigasi ke screen dengan params yang salah atau tidak lengkap akan gagal pada saat build.
Untuk komponen yang bukan children langsung dari screen, gunakan useNavigation<NativeStackNavigationProp<RootStackParamList>>() untuk mendapatkan type safety yang sama tanpa prop drilling.
Membangun TurboModule Type-Safe dengan Codegen
TurboModules menggantikan sistem Native Modules lama. File spesifikasi TypeScript berperan sebagai single source of truth, dan Codegen menghasilkan native interfaces darinya. Jika spesifikasi dan implementasi native berbeda, build akan gagal.
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
getDeviceModel(): string;
getBatteryLevel(): Promise<number>;
getStorageInfo(): Promise<{
totalBytes: number;
freeBytes: number;
usedPercentage: number;
}>;
onBatteryChange(callback: (level: number) => void): void;
}
export default TurboModuleRegistry.getEnforcing<Spec>('DeviceInfo');Menjalankan npx react-native codegen menghasilkan interface C++, Objective-C++, dan Java yang sesuai. Implementasi native harus mencocokkan setiap method signature dengan tepat. Sebagai contoh, getStorageInfo harus mengembalikan object dengan tiga field numerik; mengembalikan shape berbeda akan menyebabkan compile-time error di sisi native.
class DeviceInfoModule(reactContext: ReactApplicationContext) :
NativeDeviceInfoSpec(reactContext) {
// Return type enforced by generated NativeDeviceInfoSpec
override fun getDeviceModel(): String {
return Build.MODEL
}
override fun getBatteryLevel(): Promise<Double> {
val bm = reactContext.getSystemService(Context.BATTERY_SERVICE)
as BatteryManager
val level = bm.getIntProperty(
BatteryManager.BATTERY_PROPERTY_CAPACITY
).toDouble()
return Promise.resolve(level)
}
}Pendekatan ini menghilangkan parsing ReadableMap dan NSDictionary yang menyebabkan bug silent type coercion pada arsitektur lama. Untuk pembahasan lebih mendalam tentang sistem native module, lihat pertanyaan wawancara native modules.
Siap menguasai wawancara React Native Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Generic Data Fetching dengan Typed API Hooks
Pola typed hook yang dapat digunakan kembali menghindari duplikasi fetch logic di berbagai screen sambil mempertahankan type inference secara penuh:
import { useQuery, UseQueryOptions } from '@tanstack/react-query';
interface ApiResponse<T> {
data: T;
meta: { page: number; totalPages: number };
}
export function useApiQuery<T>(
key: readonly string[],
endpoint: string,
options?: Omit<UseQueryOptions<ApiResponse<T>>, 'queryKey' | 'queryFn'>
) {
return useQuery<ApiResponse<T>>({
queryKey: key,
queryFn: async () => {
const response = await fetch(`${API_BASE}${endpoint}`);
if (!response.ok) throw new ApiError(response.status);
return response.json() as Promise<ApiResponse<T>>;
},
...options,
});
}
// Usage, T is inferred as Article[]
interface Article {
id: string;
title: string;
publishedAt: string;
}
const { data, isLoading } = useApiQuery<Article[]>(
['articles', 'latest'],
'/articles?sort=latest'
);
// data.data is Article[], fully typed
// data.meta.totalPages is numberParameter generik T mengalir melalui seluruh chain: dari titik pemanggilan hook, melalui query function, hingga komponen yang mengonsumsi hasilnya. Tanpa as casts, tanpa any types.
Discriminated Unions untuk State Machines
State screen yang kompleks (loading, error, empty, loaded) sebaiknya dimodelkan sebagai discriminated unions alih-alih kumpulan optional fields:
type ScreenState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'error'; error: string; retryCount: number }
| { status: 'empty'; message: string }
| { status: 'loaded'; data: T; refreshedAt: Date };
// components/DataScreen.tsx
function renderContent<T>(state: ScreenState<T>, renderItem: (data: T) => ReactNode) {
switch (state.status) {
case 'idle':
return null;
case 'loading':
return <LoadingSpinner />;
case 'error':
// state.error is string here, TypeScript narrows automatically
return <ErrorBanner message={state.error} retries={state.retryCount} />;
case 'empty':
return <EmptyState message={state.message} />;
case 'loaded':
// state.data is T, fully typed
return renderItem(state.data);
}
}Pola ini membuat impossible states tidak dapat direpresentasikan. State loading tidak dapat secara tidak sengaja membawa data lama, dan state error selalu menyertakan konteks untuk debugging.
Anti-pattern yang umum: { isLoading: boolean; error?: string; data?: T }. Pola ini memungkinkan state seperti { isLoading: true, error: 'fail', data: [...] }, tiga sinyal yang saling bertentangan sekaligus. Discriminated unions mencegah hal ini pada level tipe.
Pertanyaan Wawancara React Native TypeScript
Pertanyaan-pertanyaan ini mencerminkan apa yang ditanyakan tim senior mobile engineering dalam wawancara 2026, setelah New Architecture dan TypeScript menjadi standar.
Bagaimana Codegen menegakkan type safety di batas JavaScript-native?
Codegen membaca file spesifikasi TypeScript (atau Flow) dan menghasilkan kode interface C++, Objective-C++, dan Java/Kotlin. Interface native yang dihasilkan menegakkan method signatures, parameter types, dan return types yang tepat sesuai definisi dalam spec. Jika implementasi native menyimpang (mengembalikan Int padahal spec mendeklarasikan Double, atau menghilangkan field dari struct), compiler native akan menolak build. Ini memindahkan error tipe dari runtime crashes ke build-time failures.
Apa itu Strict TypeScript API dan mengapa itu penting?
Strict TypeScript API menghasilkan types langsung dari source code React Native alih-alih memelihara file .d.ts yang ditulis tangan. Di 0.87, fitur ini menjadi default wajib. Fitur ini membatasi imports ke root package react-native, mendepresiasi deep imports. Ini mendefinisikan API surface publik yang stabil: refactoring internal tidak dapat merusak kode consumer jika consumer hanya menggunakan strict types. Opt-out sementara melalui customConditions tetap tersedia hingga 0.88.
Bagaimana cara mengetik React Navigation params di nested navigators?
Definisikan tipe ParamList per navigator dan gabungkan menggunakan NavigatorScreenParams. Untuk tab navigator yang bersarang di dalam stack, param list stack mereferensikan tab's: type RootStack = { Main: NavigatorScreenParams<TabParamList>; Modal: { id: string } }. Setiap panggilan navigate() kemudian diperiksa tipe-nya melalui seluruh hierarki nesting, menangkap nama screen yang salah atau params yang hilang pada saat compile time.
Masalah apa yang dipecahkan discriminated unions dalam React Native state management?
Discriminated unions memodelkan state yang saling eksklusif (loading, error, loaded) sebagai branch terpisah dari union type, dengan key berupa field status. TypeScript mempersempit tipe di setiap branch switch statement, sehingga mengakses state.data hanya mungkin ketika state.status === 'loaded'. Ini mencegah impossible states seperti loading indicator yang tampil bersamaan dengan error data, kategori bug yang tidak dapat dicegah oleh optional fields dan boolean flags.
Jelaskan perbedaan antara TurboModules dan sistem Native Modules lama.
Native Modules berkomunikasi melalui async bridge, men-serialize semua data ke JSON. TurboModules menggunakan JSI (JavaScript Interface) untuk panggilan C++ yang sinkron dan langsung tanpa serialization overhead. TurboModules juga memuat secara lazy (saat penggunaan pertama, bukan saat startup aplikasi, mengurangi cold start time) dan menggunakan Codegen untuk menghasilkan interface type-safe dari TypeScript specs. Sistem lama bergantung pada parsing ReadableMap / NSDictionary dengan runtime type coercion; TurboModules menegakkan types pada saat compile time.
API apa saja yang dihapus di React Native 0.87?
0.87 menghapus InteractionManager (gunakan requestIdleCallback), tipe NativeMethods / NativeMethodsMixin (gunakan HostInstance), dan beberapa props StatusBar. Deep imports ke path src/private/ kini menjadi type errors. Flag useTurboModules juga dihapus karena TurboModules kini selalu diaktifkan.
Untuk lebih banyak pertanyaan wawancara React Native, panduan lengkap mencakup topik arsitektur, performa, dan debugging.
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Sources
- React Native 0.87 Release Notes - Strict TypeScript API default, persyaratan toolchain, penghapusan API
- React Native TypeScript Documentation - Panduan setup TypeScript resmi
- React Navigation TypeScript Guide - Pola typed navigation
- TanStack Query Documentation - Data fetching dengan type inference
Yang Perlu Diingat Tentang React Native TypeScript di 2026
- Strict TypeScript API (wajib di 0.87) membatasi imports ke API surface publik yang stabil, mencegah kerusakan akibat perubahan internal. Opt-out untuk legacy deep imports tersedia hingga 0.88 saja.
- Codegen menghasilkan native interfaces dari file spesifikasi TypeScript, memindahkan error tipe dari runtime crashes ke build-time failures di batas JS-native
- Minimum toolchain di 0.87: Node.js 22.13+, Kotlin 2.0+, AGP 9, compileSdk 34+
- Typed navigation params melalui
RootStackParamListdanNativeStackScreenPropsmenangkap nama screen yang salah dan params yang hilang sebelum aplikasi berjalan - Discriminated unions memodelkan state screen sebagai branch yang saling eksklusif, membuat impossible states tidak dapat direpresentasikan pada level tipe
- TurboModules dengan typed specs menggantikan parsing
ReadableMap/NSDictionarylama, menegakkan type safety penuh dari JavaScript melalui C++ ke kode platform-native - Generic API hooks dengan TanStack Query mempertahankan type inference dari endpoint ke komponen tanpa cast manual
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Bisakah kamu menemukan bug di React Native?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 25 Agustus 2026
Tag
Bagikan
Artikel terkait

React Native 0.85 di 2026: Animation Backend Baru, TypeScript Strict API, dan Pertanyaan Interview
React Native 0.85 menghadirkan Shared Animation Backend, arsitektur post-bridge, dan Metro TLS. Pembahasan mendalam dengan contoh kode dan pertanyaan interview.

Pengembangan Aplikasi React Native 2026: Panduan Lengkap dan Pertanyaan Interview
Panduan komprehensif pengembangan aplikasi React Native di tahun 2026. Pelajari New Architecture, JSI, Fabric, TurboModules, dan pertanyaan interview yang sering ditanyakan.

React Native New Architecture 2026: Panduan Lengkap Hermes V1, Fabric, dan TurboModules
Pelajari arsitektur baru React Native secara mendalam termasuk Hermes V1, Fabric Renderer, TurboModules, dan Bridgeless Mode. Panduan teknis lengkap untuk developer mobile di tahun 2026.