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

การพัฒนา React Native ด้วย TypeScript ในปี 2026 ได้ก้าวเข้าสู่จุดเปลี่ยนสำคัญ เมื่อเวอร์ชัน 0.86 ที่มาพร้อมกับ React 19.1, Strict TypeScript API และสถาปัตยกรรมแบบ bridgeless ที่ขับเคลื่อนด้วย Codegen ได้รับการเผยแพร่อย่างเป็นทางการ TypeScript ไม่ใช่เพียงตัวเลือกเสริมสำหรับเชื่อมต่อระหว่าง JavaScript กับ native code อีกต่อไป แต่ได้กลายเป็นสัญญาหลัก (contract) ที่ควบคุมทุกอย่างตั้งแต่ component props ไปจนถึง TurboModule interfaces ทำให้สามารถตรวจจับข้อผิดพลาดได้ตั้งแต่ขั้นตอน build แทนที่จะรอให้เกิด crash logs ใน production ความเปลี่ยนแปลงนี้ส่งผลกระทบอย่างมากต่อวิธีการออกแบบสถาปัตยกรรมแอปพลิเคชัน รวมถึงมาตรฐานการประเมินผู้สมัครในการสัมภาษณ์งานตำแหน่ง mobile developer
React Native 0.80 เปิดตัว Strict TypeScript API แบบ opt-in, เวอร์ชัน 0.82 ลบ legacy bridge อย่างถาวร และเวอร์ชัน 0.85 ลบ interop layer สุดท้ายออกไป ณ เวอร์ชัน 0.86 (มิถุนายน 2026) ทุกโปรเจกต์ใหม่จะเริ่มต้นแบบ fully bridgeless พร้อม TypeScript types ที่ถูก generate โดยตรงจาก source code
ทำไม TypeScript จึงเป็นค่าเริ่มต้นของโปรเจกต์ React Native
ตั้งแต่เวอร์ชัน 0.76 เป็นต้นมา ทุกครั้งที่รันคำสั่ง npx react-native init ระบบจะสร้างโปรเจกต์แบบ TypeScript โดยอัตโนมัติ อย่างไรก็ตาม การเปลี่ยนแปลงที่สำคัญจริงเกิดขึ้นที่ขอบเขตระหว่าง JavaScript กับ native code ก่อนที่จะมี Codegen นักพัฒนาต้องเขียน type assertions ด้วยตนเองเมื่อข้อมูลข้ามจาก JavaScript ไปยัง Objective-C หรือ Kotlin ซึ่งเป็นสัญญาแบบ stringly-typed ที่มักเกิดข้อผิดพลาดแบบเงียบในขณะรันไทม์โดยไม่มีสัญญาณเตือน
Codegen แก้ปัญหานี้โดยการอ่าน TypeScript spec files แล้ว generate C++, Objective-C++ และ Java/Kotlin interfaces โดยอัตโนมัติ หากไฟล์ spec ประกาศว่า method คืนค่าเป็น number interface ที่ถูก generate ฝั่ง native จะบังคับข้อจำกัดนั้นในขั้นตอน compile time ทันที
เอกสาร React Native อย่างเป็นทางการ ครอบคลุมการตั้งค่าเบื้องต้น แต่รูปแบบ type-safe ที่มีความสำคัญใน production นั้นลึกซึ้งกว่า ได้แก่ typed navigation stacks, generic API hooks, discriminated unions สำหรับ state machines และ Codegen-driven TurboModule specs
การตั้งค่า Strict TypeScript API
Strict TypeScript API ที่เปิดตัวใน React Native 0.80 จำกัด public API surface ให้เหลือเฉพาะ types ที่ถูก generate โดยตรงจาก source code ของ React Native เท่านั้น การตั้งค่านี้ป้องกันการพึ่งพา internal modules โดยไม่ตั้งใจ ซึ่งอาจเปลี่ยนแปลงได้ระหว่างเวอร์ชันย่อย
{
"compilerOptions": {
"strict": true,
"exactOptionalPropertyTypes": true,
"noUncheckedIndexedAccess": true,
"moduleResolution": "bundler",
"jsx": "react-jsx",
"types": ["react-native/types/strict"]
},
"extends": "@react-native/typescript-config/tsconfig.json"
}เมื่อใช้การตั้งค่านี้ การ import จาก subpath เช่น react-native/Libraries/Text/Text จะทำให้เกิด type error ทันที ทุก import ต้องมาจาก root react-native package เท่านั้น ซึ่งสอดคล้องกับนโยบาย deep-import deprecation ที่บังคับใช้ตั้งแต่เวอร์ชัน 0.80 เป็นต้นมา
ตัวเลือก exactOptionalPropertyTypes บังคับให้แยกความแตกต่างระหว่าง property ที่เป็น undefined กับ property ที่ไม่มีอยู่จริง ส่วน noUncheckedIndexedAccess เพิ่ม | undefined ให้กับทุก index access ทำให้ต้องตรวจสอบค่าก่อนใช้งาน ทั้งสองตัวเลือกนี้ช่วยลดบั๊กที่เกิดจากสมมติฐานผิดเกี่ยวกับโครงสร้างข้อมูลได้อย่างมีประสิทธิภาพ
Type-Safe Navigation ด้วย React Navigation 7
React Navigation 7.x มี TypeScript support ระดับ first-class รูปแบบหลักคือการกำหนด RootStackParamList type ที่ 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' }) — type-checked
// navigation.navigate('Profile', {}) — compile error: missing userId
return (
<ArticleView id={articleId} referrer={source} />
);
}รูปแบบนี้กำจัดข้อผิดพลาดรันไทม์ทั้ง class ออกไป การ navigate ไปยัง screen ด้วย params ที่ผิดหรือขาดหายไปจะล้มเหลวตั้งแต่ขั้นตอน build ไม่ใช่ตอนที่ผู้ใช้งานกำลังใช้แอป ประโยชน์นี้ยิ่งชัดเจนในแอปพลิเคชันขนาดใหญ่ที่มี screen จำนวนมากและ navigation flow ที่ซับซ้อน
สำหรับ components ที่ไม่ได้เป็น screen children โดยตรง สามารถใช้ useNavigation<NativeStackNavigationProp<RootStackParamList>>() เพื่อให้ได้ type safety เท่าเทียมกันโดยไม่ต้อง prop drilling ลงไปในลำดับชั้น
การสร้าง TurboModule แบบ Type-Safe ด้วย Codegen
TurboModules เข้ามาแทนที่ระบบ Native Modules เดิม ไฟล์ TypeScript spec ทำหน้าที่เป็นแหล่งข้อมูลความจริงเพียงแหล่งเดียว (single source of truth) โดย 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 C++, Objective-C++ และ Java interfaces ที่ตรงกัน native implementation ต้อง match ทุก method signature อย่างถูกต้อง ตัวอย่างเช่น getStorageInfo ต้องคืนค่า object ที่มี field ตัวเลขสามตัว หากคืนค่าในรูปแบบอื่นจะเกิด 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 ที่เคยเป็นสาเหตุของบั๊ก silent type coercion ในสถาปัตยกรรมเดิม ทุกอย่างถูกตรวจสอบตั้งแต่ขั้นตอน compile ทำให้ข้อผิดพลาดที่เกี่ยวกับ type ไม่สามารถหลุดรอดไปถึง production ได้
พร้อมที่จะพิชิตการสัมภาษณ์ React Native แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
Generic Data Fetching ด้วย Typed API Hooks
รูปแบบ typed hook ที่ใช้ซ้ำได้ช่วยหลีกเลี่ยงการเขียน fetch logic ซ้ำในทุก screen พร้อมรักษา 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 ปรากฏในโค้ด ข้อดีของรูปแบบนี้คือเมื่อเปลี่ยนโครงสร้างข้อมูลของ API (เช่น เพิ่ม field ใหม่หรือเปลี่ยนชนิดข้อมูล) TypeScript จะแจ้ง error ในทุกจุดที่ได้รับผลกระทบทันที ทำให้ refactoring ปลอดภัยและมั่นใจมากขึ้น
Discriminated Unions สำหรับ State Machines
สถานะหน้าจอที่ซับซ้อน เช่น loading, error, empty และ loaded ควรถูกจำลองด้วย 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);
}
}รูปแบบนี้ทำให้สถานะที่เป็นไปไม่ได้ไม่สามารถแสดงออกในโค้ดได้ (impossible states are unrepresentable) สถานะ loading ไม่สามารถแบกข้อมูลเก่า (data) ติดไปได้โดยไม่ตั้งใจ และสถานะ error จะมีข้อมูลบริบทสำหรับ debug เสมอ TypeScript จะ narrow type โดยอัตโนมัติในแต่ละ branch ของ switch statement ทำให้การเข้าถึง properties ที่ไม่มีอยู่ในสถานะนั้นเกิด compile error ทันที
Anti-pattern ที่พบบ่อย: { isLoading: boolean; error?: string; data?: T } รูปแบบนี้อนุญาตให้เกิดสถานะอย่าง { isLoading: true, error: 'fail', data: [...] } ซึ่งมีสัญญาณที่ขัดแย้งกันสามอย่างพร้อมกัน Discriminated unions ป้องกันปัญหานี้ได้ในระดับ type system
คำถามสัมภาษณ์งาน React Native TypeScript
คำถามเหล่านี้สะท้อนสิ่งที่ทีม mobile engineering ระดับ senior ถามในการสัมภาษณ์ปี 2026 เมื่อ New Architecture และ TypeScript กลายเป็นมาตรฐาน
Codegen บังคับ type safety ข้ามขอบเขต JavaScript-native ได้อย่างไร
Codegen อ่าน TypeScript (หรือ Flow) spec files แล้ว generate C++, Objective-C++ และ Java/Kotlin interface code ตัว generated native interfaces บังคับ method signatures, parameter types และ return types ที่ตรงกับ spec อย่างเข้มงวด หาก native implementation เบี่ยงเบน เช่น คืนค่า Int ในจุดที่ spec กำหนดเป็น Double หรือละเว้น field จาก struct คอมไพเลอร์ฝั่ง native จะปฏิเสธ build ทันที การทำเช่นนี้ย้ายข้อผิดพลาดเกี่ยวกับ type จาก runtime crashes ไปเป็น build-time failures
Strict TypeScript API คืออะไร และทำไมจึงสำคัญ
Strict TypeScript API ที่เปิดตัวใน React Native 0.80 generate types โดยตรงจาก source code ของ React Native แทนที่จะดูแล hand-written .d.ts files ระบบจำกัดการ import ให้เฉพาะจาก root react-native package เท่านั้น โดย deprecate deep imports ทั้งหมด สิ่งนี้กำหนด public API surface ที่เสถียร ทำให้การ refactor ภายในไม่สามารถทำลายโค้ดของผู้ใช้งานได้ตราบใดที่ใช้ strict types เปิดใช้งานผ่าน "types": ["react-native/types/strict"] ใน tsconfig.json
จะกำหนด type ให้ React Navigation params ข้าม nested navigators ได้อย่างไร
กำหนด ParamList type ต่อ navigator หนึ่งตัว แล้วประกอบเข้าด้วยกันด้วย NavigatorScreenParams สำหรับ tab navigator ที่ซ้อนอยู่ภายใน stack param list ของ stack จะอ้างอิงถึง tab's: type RootStack = { Main: NavigatorScreenParams<TabParamList>; Modal: { id: string } } ทุกการเรียก navigate() จะถูก type-checked ผ่านลำดับชั้นทั้งหมด ตรวจจับชื่อ screen ผิดหรือ params ที่ขาดหายไปตั้งแต่ขั้นตอน compile time
Discriminated unions แก้ปัญหาอะไรใน React Native state management
Discriminated unions จำลองสถานะที่เป็น mutually exclusive (loading, error, loaded) เป็น branches แยกของ union type โดยใช้ status field เป็นตัวแยก TypeScript narrows type ในแต่ละ branch ของ switch statement ทำให้การเข้าถึง state.data เป็นไปได้เฉพาะเมื่อ state.status === 'loaded' เท่านั้น รูปแบบนี้ป้องกันสถานะที่เป็นไปไม่ได้ เช่น loading indicator แสดงพร้อมกับ error data ซึ่ง optional fields และ boolean flags ไม่สามารถป้องกันได้
อธิบายความแตกต่างระหว่าง TurboModules กับระบบ Native Modules เดิม
Native Modules สื่อสารผ่าน async bridge โดย serialize ข้อมูลทั้งหมดเป็น JSON ส่วน TurboModules ใช้ JSI (JavaScript Interface) สำหรับการเรียกแบบ synchronous โดยตรงผ่าน C++ โดยไม่มี serialization overhead นอกจากนี้ TurboModules ยัง load แบบ lazy (โหลดเมื่อใช้งานครั้งแรกแทนที่จะ load ตอนเริ่มแอป ช่วยลดเวลา cold start) และใช้ Codegen generate type-safe interfaces จาก TypeScript specs ระบบเดิมพึ่งพา ReadableMap / NSDictionary parsing ที่มี runtime type coercion แต่ TurboModules บังคับ types ตั้งแต่ขั้นตอน compile time
สำหรับคำถามสัมภาษณ์ React Native เพิ่มเติม หัวข้อ native modules deep-dive ครอบคลุม JSI, Fabric และสถาปัตยกรรม bridgeless อย่างละเอียด
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
สรุป
- Strict TypeScript API (0.80+) จำกัดการ import ให้เฉพาะ public API surface ที่เสถียร ป้องกันการเปลี่ยนแปลงภายในทำลายโค้ด ควรเปิดใช้งานในทุกโปรเจกต์ใหม่
- Codegen generate native interfaces จาก TypeScript spec files ย้ายข้อผิดพลาดเกี่ยวกับ type จาก runtime crashes ไปเป็น build-time failures ข้ามขอบเขต JS-native
- Typed navigation params ผ่าน
RootStackParamListและNativeStackScreenPropsตรวจจับชื่อ screen ผิดและ params ที่ขาดหายไปก่อนที่แอปจะรัน - Discriminated unions จำลองสถานะหน้าจอเป็น branches ที่เป็น mutually exclusive ทำให้สถานะที่เป็นไปไม่ได้ไม่สามารถแสดงออกในระดับ type system
- 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 0.85 ในปี 2026: Animation Backend ใหม่, Strict TypeScript API และคำถามสัมภาษณ์
React Native 0.85 เปิดตัว Shared Animation Backend, สถาปัตยกรรม post-bridge และ Metro TLS วิเคราะห์เชิงลึกพร้อมตัวอย่างโค้ดและคำถามสัมภาษณ์

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

Expo Router สำหรับ React Native: คู่มือระบบ Navigation แบบ File-Based ฉบับสมบูรณ์
คู่มือฉบับสมบูรณ์สำหรับ Expo Router ใน React Native ครอบคลุมระบบ routing แบบ file-based, การตั้งค่า layout, tab navigation, dynamic routes, modal screens, typed routes, middleware และการป้องกันเส้นทาง พร้อมตัวอย่างโค้ดจริง