React Native และ TypeScript ปี 2026: สถาปัตยกรรม Type-Safe และคำถามสัมภาษณ์
สร้างแอป React Native แบบ type-safe ด้วย TypeScript, Codegen, TurboModules และ Strict TypeScript API ครอบคลุม patterns สถาปัตยกรรม, typed navigation, ข้อกำหนด toolchain 0.87 และคำถามสัมภาษณ์

React Native TypeScript type safety เติบโตอย่างมีนัยสำคัญในช่วงกลางปี 2026 โดยเวอร์ชัน 0.87 ทำให้ Strict TypeScript API เป็นค่าเริ่มต้นแบบบังคับ และเสร็จสิ้นการปรับปรุง toolchain ครั้งใหญ่ TypeScript ไม่ใช่แค่ตัวเชื่อมต่อทางเลือกระหว่าง JavaScript และ native code อีกต่อไป: มันขับเคลื่อน contract ทั้งหมดตั้งแต่ component props ไปจนถึง TurboModule interfaces ตรวจจับความไม่ตรงกันของ type ในขั้นตอน build แทนที่จะปรากฏใน crash logs ของ production
React Native 0.87 (สิงหาคม 2026) ทำให้ Strict TypeScript API เป็นค่าเริ่มต้นบังคับ นอกจากนี้ยังยกระดับข้อกำหนดขั้นต่ำเป็น Node.js 22.13+, Kotlin 2.0+ และ Android Gradle Plugin 9 ตัวเลือก opt-out สำหรับ legacy deep imports ยังคงใช้ได้จนถึง 0.88 เท่านั้น
ทำไม TypeScript จึงเป็นค่าเริ่มต้นสำหรับโปรเจกต์ React Native
ทุกคำสั่ง npx react-native init ตั้งแต่เวอร์ชัน 0.76 สร้าง scaffolding โปรเจกต์ TypeScript แต่การเปลี่ยนแปลงที่แท้จริงเกิดขึ้นที่ขอบเขต native ก่อนที่จะมี Codegen นักพัฒนาเขียน type assertions ด้วยตนเองเมื่อข้ามจาก JavaScript ไปยัง Objective-C หรือ Kotlin ซึ่งเป็น contract แบบ stringly-typed ที่ล้มเหลวอย่างเงียบเชียบในขณะ runtime Codegen อ่านไฟล์ TypeScript spec และ generate interface สำหรับ C++, Objective-C++ และ Java/Kotlin โดยอัตโนมัติ หาก TypeScript spec ประกาศว่า method คืนค่าเป็น number native interface ที่ถูก generate จะบังคับข้อจำกัดนั้นในขั้นตอน compile time
เอกสาร React Native ครอบคลุมการตั้งค่าพื้นฐาน แต่ pattern แบบ type-safe ที่สำคัญใน production นั้นลึกกว่า: typed navigation stacks, generic API hooks, discriminated unions สำหรับ state machines และ TurboModule specs ที่ขับเคลื่อนโดย Codegen
Strict TypeScript API: จาก Opt-In สู่ค่าเริ่มต้น
Strict TypeScript API เปิดตัวใน React Native 0.80 เป็นฟีเจอร์แบบ opt-in ตั้งแต่ 0.87 เป็นต้นไป มันเป็นค่าเริ่มต้นบังคับสำหรับโปรเจกต์ใหม่ทั้งหมด Types ถูก generate โดยตรงจาก source code ของ React Native แทนที่จะดูแลด้วยตนเอง ขจัดความคลาดเคลื่อนระหว่าง API ที่เป็นเอกสารและ implementation จริง
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
"strict": true,
"exactOptionalPropertyTypes": true,
"noUncheckedIndexedAccess": true
}
}ด้วยการกำหนดค่านี้ การ import อะไรก็ตามจาก subpath เช่น react-native/Libraries/Text/Text จะทำให้เกิด type error ทุก import ต้องมาจาก root package react-native หากไลบรารีหรือ codebase เก่ายังคงพึ่งพา deep imports มีตัวเลือก opt-out ชั่วคราวจนถึง 0.88:
{
"extends": "@react-native/typescript-config",
"compilerOptions": {
"customConditions": ["react-native", "react-native-legacy-deep-imports"]
}
}ตัวเลือก opt-out นี้จะถูกลบใน 0.89 การย้ายควรเกิดขึ้นก่อนนั้น
ข้อกำหนด Toolchain ใน 0.87
React Native 0.87 ยกระดับเวอร์ชันขั้นต่ำทั่วทั้ง build chain:
| ส่วนประกอบ | ขั้นต่ำ |
|---|---|
| Node.js | 22.13.0 |
| Kotlin | 2.0 (bundled: 2.2.0) |
| Android Gradle Plugin | 9.x |
| Android compileSdk | 34 (min), 37 (target) |
สำหรับ Android, AGP 9 ต้องการการกำหนดค่าเพิ่มเติม:
# android/gradle.properties
android.builtInKotlin=false
android.newDsl=falseข้อกำหนดเหล่านี้ใช้กับทุกโปรเจกต์ที่กำหนดเป้าหมาย 0.87+ คู่มือการย้าย New Architecture ครอบคลุมบริบทที่กว้างขึ้นของการเปลี่ยนแปลงเหล่านี้
Type-Safe Navigation ด้วย React Navigation 7
React Navigation 7.x ให้การสนับสนุน TypeScript ระดับ first-class pattern หลัก: กำหนด type RootStackParamList ที่ map ทุกชื่อ screen ไปยัง params ที่คาดหวัง จากนั้นส่ง type นั้นผ่าน navigators และ 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 จะได้รับ typed props โดยไม่ต้อง cast ด้วยตนเอง:
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} />
);
}วิธีการนี้กำจัด class ของ runtime errors ทั้งหมด: การ navigate ไปยัง screen ด้วย params ที่ผิดหรือขาดหายจะล้มเหลวตอน build time
สำหรับ components ที่ไม่ใช่ screen children โดยตรง ใช้ useNavigation<NativeStackNavigationProp<RootStackParamList>>() เพื่อให้ได้ type safety เดียวกันโดยไม่ต้อง prop drilling
การสร้าง TurboModule แบบ Type-Safe ด้วย Codegen
TurboModules แทนที่ระบบ Native Modules เดิม ไฟล์ TypeScript spec ทำหน้าที่เป็นแหล่งความจริงเดียว และ Codegen generate native interfaces จากมัน หาก spec และ native implementation แตกต่างกัน build จะล้มเหลว
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');การรัน npx react-native codegen จะ generate interface C++, Objective-C++ และ Java ที่สอดคล้องกัน native implementation ต้องตรงกับทุก method signature อย่างแม่นยำ ตัวอย่างเช่น getStorageInfo ต้องคืนค่า object ที่มี field ตัวเลขสามตัว การคืนค่า shape ที่ต่างกันจะทำให้เกิด compile-time error ฝั่ง 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)
}
}วิธีการนี้กำจัดการ parse ReadableMap และ NSDictionary ที่เคยทำให้เกิด bug แบบ silent type coercion ในสถาปัตยกรรมเดิม สำหรับการศึกษาเชิงลึกเกี่ยวกับระบบ native module ดู คำถามสัมภาษณ์ native modules
พร้อมที่จะพิชิตการสัมภาษณ์ React Native แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
Generic Data Fetching ด้วย Typed API Hooks
pattern typed hook ที่ใช้ซ้ำได้หลีกเลี่ยงการซ้ำ fetch logic ข้าม screens ในขณะที่รักษา type inference อย่างเต็มที่:
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 numbergeneric parameter T ไหลผ่านทั้งสาย: จากจุดเรียก hook ผ่าน query function ไปยัง component ที่ใช้ผลลัพธ์ ไม่มี as casts ไม่มี any types
Discriminated Unions สำหรับ State Machines
สถานะ screen ที่ซับซ้อน (loading, error, empty, loaded) ควรถูก model เป็น discriminated unions แทนที่จะเป็นกลุ่มของ 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);
}
}pattern นี้ทำให้ impossible states ไม่สามารถแสดงออกได้ สถานะ loading ไม่สามารถพก data เก่าโดยไม่ตั้งใจ และสถานะ error จะมี context สำหรับ debugging เสมอ
anti-pattern ที่พบบ่อย: { isLoading: boolean; error?: string; data?: T } pattern นี้อนุญาตให้มีสถานะเช่น { isLoading: true, error: 'fail', data: [...] } สามสัญญาณที่ขัดแย้งกันพร้อมกัน Discriminated unions ป้องกันสิ่งนี้ในระดับ type
คำถามสัมภาษณ์ React Native TypeScript
คำถามเหล่านี้สะท้อนสิ่งที่ทีม mobile engineering ระดับ senior ถามในการสัมภาษณ์ปี 2026 เมื่อ New Architecture และ TypeScript เป็นมาตรฐานแล้ว
Codegen บังคับ type safety ข้ามขอบเขต JavaScript-native อย่างไร?
Codegen อ่านไฟล์ TypeScript (หรือ Flow) spec และ generate โค้ด interface สำหรับ C++, Objective-C++ และ Java/Kotlin native interface ที่ถูก generate บังคับ method signatures, parameter types และ return types ที่แน่นอนตามที่กำหนดใน spec หาก native implementation เบี่ยงเบน (คืนค่า Int ที่ spec ประกาศ Double หรือละเว้น field จาก struct) native compiler จะปฏิเสธ build สิ่งนี้ย้าย type errors จาก runtime crashes ไปเป็น build-time failures
Strict TypeScript API คืออะไรและทำไมจึงสำคัญ?
Strict TypeScript API generate types โดยตรงจาก source code ของ React Native แทนที่จะดูแลไฟล์ .d.ts ที่เขียนด้วยมือ ใน 0.87 มันกลายเป็นค่าเริ่มต้นบังคับ มันจำกัด imports ไปยัง root package react-native deprecate deep imports สิ่งนี้กำหนด public API surface ที่เสถียร: การ refactor ภายในไม่สามารถทำลายโค้ดของ consumer ได้หาก consumers ใช้เฉพาะ strict types ตัวเลือก opt-out ชั่วคราวผ่าน customConditions ยังคงใช้ได้จนถึง 0.88
จะ type React Navigation params ข้าม nested navigators ได้อย่างไร?
กำหนด type ParamList ต่อ navigator และรวมกันโดยใช้ NavigatorScreenParams สำหรับ tab navigator ที่ซ้อนอยู่ใน stack param list ของ stack อ้างอิงถึง tab's: type RootStack = { Main: NavigatorScreenParams<TabParamList>; Modal: { id: string } } ทุกการเรียก navigate() จะถูก type-checked ผ่านลำดับชั้น nesting ทั้งหมด จับชื่อ screen ที่ผิดหรือ params ที่ขาดหายในขั้นตอน compile time
Discriminated unions แก้ปัญหาอะไรใน React Native state management?
Discriminated unions model สถานะที่ขัดกัน (loading, error, loaded) เป็น branches แยกของ union type โดยใช้ field status เป็น key TypeScript narrow type ในแต่ละ branch ของ switch statement ดังนั้นการเข้าถึง state.data จะเป็นไปได้เฉพาะเมื่อ state.status === 'loaded' เท่านั้น สิ่งนี้ป้องกัน impossible states เช่น loading indicator แสดงพร้อมกับ error data ซึ่งเป็น class ของ bugs ที่ optional fields และ boolean flags ไม่สามารถป้องกันได้
อธิบายความแตกต่างระหว่าง TurboModules และระบบ Native Modules เดิม
Native Modules สื่อสารผ่าน async bridge serialize ข้อมูลทั้งหมดเป็น JSON TurboModules ใช้ JSI (JavaScript Interface) สำหรับการเรียก C++ แบบ synchronous โดยตรงโดยไม่มี serialization overhead นอกจากนี้ยัง load แบบ lazy (เมื่อใช้ครั้งแรกแทนที่จะตอนเริ่ม app ลด cold start time) และใช้ Codegen เพื่อ generate interface แบบ type-safe จาก TypeScript specs ระบบเดิมพึ่งพาการ parse ReadableMap / NSDictionary ด้วย runtime type coercion; TurboModules บังคับ types ตอน compile time
API อะไรบ้างที่ถูกลบใน React Native 0.87?
0.87 ลบ InteractionManager (ใช้ requestIdleCallback), types NativeMethods / NativeMethodsMixin (ใช้ HostInstance) และ props บางอย่างของ StatusBar Deep imports ไปยัง paths src/private/ ตอนนี้เป็น type errors flag useTurboModules ก็ถูกลบเช่นกันเนื่องจาก TurboModules ถูกเปิดใช้งานเสมอ
สำหรับคำถามสัมภาษณ์ React Native เพิ่มเติม คู่มือฉบับสมบูรณ์ครอบคลุมหัวข้อเกี่ยวกับสถาปัตยกรรม ประสิทธิภาพ และการ debug
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
Sources
- React Native 0.87 Release Notes - Strict TypeScript API เป็นค่าเริ่มต้น, ข้อกำหนด toolchain, การลบ API
- React Native TypeScript Documentation - คู่มือการตั้งค่า TypeScript อย่างเป็นทางการ
- React Navigation TypeScript Guide - patterns สำหรับ typed navigation
- TanStack Query Documentation - Data fetching พร้อม type inference
สิ่งที่ต้องจำเกี่ยวกับ React Native TypeScript ในปี 2026
- Strict TypeScript API (บังคับใน 0.87) จำกัด imports ไปยัง public API surface ที่เสถียร ป้องกันความเสียหายจากการเปลี่ยนแปลงภายใน ตัวเลือก opt-out สำหรับ legacy deep imports ใช้ได้จนถึง 0.88 เท่านั้น
- Codegen generate native interfaces จากไฟล์ TypeScript spec ย้าย type errors จาก runtime crashes ไปเป็น build-time failures ข้ามขอบเขต JS-native
- ข้อกำหนด toolchain ขั้นต่ำใน 0.87: Node.js 22.13+, Kotlin 2.0+, AGP 9, compileSdk 34+
- Typed navigation params ผ่าน
RootStackParamListและNativeStackScreenPropsจับชื่อ screen ที่ผิดและ params ที่ขาดหายก่อนที่ app จะรัน - Discriminated unions model สถานะ screen เป็น branches ที่ขัดกัน ทำให้ impossible states ไม่สามารถแสดงออกได้ในระดับ type
- TurboModules ที่มี typed specs แทนที่การ parse
ReadableMap/NSDictionaryเดิม บังคับ type safety เต็มรูปแบบจาก JavaScript ผ่าน C++ ไปยัง platform-native code - Generic API hooks ด้วย TanStack Query รักษา type inference จาก endpoint ไปยัง component โดยไม่ต้อง cast ด้วยตนเอง
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
คุณหาบั๊กใน React Native เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 25 สิงหาคม 2569
แท็ก
แชร์
บทความที่เกี่ยวข้อง

React Native 0.85 ในปี 2026: Animation Backend ใหม่, Strict TypeScript API และคำถามสัมภาษณ์
React Native 0.85 เปิดตัว Shared Animation Backend, สถาปัตยกรรม post-bridge และ Metro TLS วิเคราะห์เชิงลึกพร้อมตัวอย่างโค้ดและคำถามสัมภาษณ์

การพัฒนาแอปพลิเคชัน React Native 2026: คู่มือฉบับสมบูรณ์และคำถามสัมภาษณ์
คู่มือครบถ้วนสำหรับการพัฒนาแอปพลิเคชัน React Native ในปี 2026 เรียนรู้ New Architecture, JSI, Fabric, TurboModules และคำถามสัมภาษณ์ที่พบบ่อย

React Native New Architecture คู่มือฉบับสมบูรณ์ 2026: Hermes V1, Fabric, TurboModules และ Bridgeless Mode
คู่มือฉบับสมบูรณ์สำหรับ React Native New Architecture ในปี 2026 ครอบคลุม Hermes V1, Fabric Renderer, TurboModules, JSI และ Bridgeless Mode พร้อมตัวอย่างโค้ดและคำถามสัมภาษณ์