# React Native e TypeScript em 2026: Arquitetura Type-Safe e Perguntas de Entrevista > Construir aplicações React Native robustas com TypeScript, Codegen, TurboModules e a API Strict TypeScript. Arquitetura type-safe, navegação tipada e perguntas de entrevista técnica para 2026. - Published: 2026-06-16 - Updated: 2026-06-16 - Author: SharpSkill - Tags: react-native, typescript, mobile-development, new-architecture, turbomodules - Reading time: 9 min --- A segurança de tipos no React Native atingiu um patamar decisivo em meados de 2026. Com a versão 0.86 lançada em junho, o framework traz React 19.1, a API Strict TypeScript e uma arquitetura completamente sem bridge alimentada pelo Codegen. O TypeScript deixou de ser uma camada opcional entre JavaScript e código nativo — agora ele governa todo o contrato, desde as props de componentes até as interfaces de TurboModules, capturando incompatibilidades em tempo de compilação em vez de nos logs de crash em produção. > **O que mudou em 2026** > > O React Native 0.80 introduziu a API Strict TypeScript como opt-in, a versão 0.82 removeu permanentemente a bridge legacy, e a 0.85 eliminou a última camada de interoperabilidade. A partir da versão 0.86 (junho de 2026), cada projeto novo inicia no modo completamente bridgeless com tipos TypeScript gerados diretamente a partir do código-fonte. ## Por que o TypeScript se tornou o padrão para projetos React Native Cada chamada de `npx react-native init` gera um projeto TypeScript desde a versão 0.76. Mas a mudança real aconteceu na fronteira nativa. Antes do Codegen, os desenvolvedores escreviam asserções de tipo manuais ao cruzar de JavaScript para Objective-C ou Kotlin — um contrato baseado em strings que falhava silenciosamente em tempo de execução. O Codegen lê os arquivos de especificação TypeScript e gera automaticamente as interfaces em C++, Objective-C++ e Java/Kotlin. Se a especificação TypeScript declara um método que retorna `number`, a interface nativa gerada impõe essa restrição em tempo de compilação. A [documentação do React Native](https://reactnative.dev/docs/typescript) cobre a configuração básica, mas os padrões type-safe que realmente importam em produção vão além: pilhas de navegação tipadas, hooks de API genéricos, uniões discriminadas para máquinas de estado e especificações de TurboModules geradas pelo Codegen. ## Configurando a API Strict TypeScript A API Strict TypeScript, introduzida no React Native 0.80, restringe a superfície da API pública aos tipos gerados diretamente a partir do código-fonte. Isso impede a dependência acidental de módulos internos que podem quebrar entre versões menores. ```json // tsconfig.json { "compilerOptions": { "strict": true, "exactOptionalPropertyTypes": true, "noUncheckedIndexedAccess": true, "moduleResolution": "bundler", "jsx": "react-jsx", "types": ["react-native/types/strict"] }, "extends": "@react-native/typescript-config/tsconfig.json" } ``` Com essa configuração, importar qualquer coisa de um subcaminho como `react-native/Libraries/Text/Text` gera um erro de tipo. Todas as importações devem vir do pacote raiz `react-native`, alinhando-se com a depreciação de importações profundas aplicada desde a versão 0.80. ## Navegação Type-Safe com React Navigation 7 O [React Navigation 7.x](https://reactnavigation.org/docs/typescript/) oferece suporte TypeScript de primeira classe. O padrão fundamental: definir um tipo `RootStackParamList` que mapeia cada nome de tela para seus parâmetros esperados e, em seguida, propagar esse tipo através dos navegadores e componentes de tela. ```typescript // navigation/types.ts 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; }; ``` Os componentes de tela recebem props tipadas sem conversão manual: ```typescript // screens/ArticleDetailScreen.tsx import type { NativeStackScreenProps } from '@react-navigation/native-stack'; import type { RootStackParamList } from '../navigation/types'; type Props = NativeStackScreenProps; export function ArticleDetailScreen({ route, navigation }: Props) { // route.params.articleId é string — garantido pelo tipo // route.params.source é 'feed' | 'search' — sem verificação em runtime const { articleId, source } = route.params; // navigation.navigate('Profile', { userId: '123' }) — verificado pelo compilador // navigation.navigate('Profile', {}) — erro de compilação: userId ausente return ( ); } ``` Esse mecanismo elimina uma classe inteira de erros em tempo de execução — navegar para uma tela com parâmetros incorretos ou ausentes falha em tempo de compilação. > **Tipagem do hook useNavigation** > > Para componentes que não são filhos diretos de uma tela, utilizar `useNavigation>()` fornece a mesma segurança de tipos sem prop drilling. ## Construindo um TurboModule Type-Safe com Codegen Os TurboModules substituem o antigo sistema de Native Modules. O arquivo de especificação TypeScript serve como a fonte única de verdade — o Codegen gera as interfaces nativas a partir dele. Se a especificação e a implementação nativa divergem, o build falha. ```typescript // specs/NativeDeviceInfo.ts import type { TurboModule } from 'react-native'; import { TurboModuleRegistry } from 'react-native'; export interface Spec extends TurboModule { getDeviceModel(): string; getBatteryLevel(): Promise; getStorageInfo(): Promise<{ totalBytes: number; freeBytes: number; usedPercentage: number; }>; onBatteryChange(callback: (level: number) => void): void; } export default TurboModuleRegistry.getEnforcing('DeviceInfo'); ``` A execução de `npx react-native codegen` gera as interfaces correspondentes em C++, Objective-C++ e Java. A implementação nativa deve corresponder exatamente a cada assinatura de método. Por exemplo, `getStorageInfo` deve retornar um objeto com três campos numéricos — retornar uma estrutura diferente causa um erro de compilação no lado nativo. ```kotlin // android/app/src/main/java/com/app/DeviceInfoModule.kt class DeviceInfoModule(reactContext: ReactApplicationContext) : NativeDeviceInfoSpec(reactContext) { // O tipo de retorno é imposto pelo NativeDeviceInfoSpec gerado override fun getDeviceModel(): String { return Build.MODEL } override fun getBatteryLevel(): Promise { val bm = reactContext.getSystemService(Context.BATTERY_SERVICE) as BatteryManager val level = bm.getIntProperty( BatteryManager.BATTERY_PROPERTY_CAPACITY ).toDouble() return Promise.resolve(level) } } ``` Essa abordagem elimina o parsing de `ReadableMap` e `NSDictionary` que causava bugs silenciosos de coerção de tipos na arquitetura anterior. ## Hooks de API Genéricos com Tipagem Completa Um padrão de hook tipado reutilizável evita a duplicação da lógica de fetch entre telas, preservando a inferência de tipos completa: ```typescript // hooks/useApiQuery.ts import { useQuery, UseQueryOptions } from '@tanstack/react-query'; interface ApiResponse { data: T; meta: { page: number; totalPages: number }; } export function useApiQuery( key: readonly string[], endpoint: string, options?: Omit>, 'queryKey' | 'queryFn'> ) { return useQuery>({ queryKey: key, queryFn: async () => { const response = await fetch(`${API_BASE}${endpoint}`); if (!response.ok) throw new ApiError(response.status); return response.json() as Promise>; }, ...options, }); } // Uso — T é inferido como Article[] interface Article { id: string; title: string; publishedAt: string; } const { data, isLoading } = useApiQuery( ['articles', 'latest'], '/articles?sort=latest' ); // data.data é Article[] — completamente tipado // data.meta.totalPages é number ``` O parâmetro genérico `T` se propaga por toda a cadeia: do ponto de chamada do hook, passando pela função de consulta, até o componente que consome o resultado. Sem casts `as`, sem tipos `any`. ## Uniões Discriminadas para Máquinas de Estado Estados de tela complexos — carregamento, erro, vazio, carregado — são melhor modelados como uniões discriminadas em vez de um conjunto de campos opcionais: ```typescript // types/screen-state.ts type ScreenState = | { 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(state: ScreenState, renderItem: (data: T) => ReactNode) { switch (state.status) { case 'idle': return null; case 'loading': return ; case 'error': // state.error é string aqui — TypeScript restringe o tipo automaticamente return ; case 'empty': return ; case 'loaded': // state.data é T — completamente tipado return renderItem(state.data); } } ``` Esse padrão torna os estados impossíveis irrepresentáveis. Um estado `loading` não pode carregar acidentalmente dados obsoletos, e um estado `error` sempre inclui contexto para depuração. > **Evitar objetos de estado parciais** > > Um anti-padrão comum: `{ isLoading: boolean; error?: string; data?: T }`. Esse esquema permite estados como `{ isLoading: true, error: 'fail', data: [...] }` — três sinais contraditórios ao mesmo tempo. As uniões discriminadas previnem isso no nível do sistema de tipos. ## Perguntas de Entrevista React Native TypeScript Estas perguntas refletem o que as equipes de engenharia móvel senior perguntam em entrevistas em 2026, agora que a New Architecture e o TypeScript se tornaram padrão. **Como o Codegen garante a segurança de tipos na fronteira JavaScript-nativo?** O Codegen lê os arquivos de especificação TypeScript (ou Flow) e gera código de interface em C++, Objective-C++ e Java/Kotlin. As interfaces nativas geradas impõem as assinaturas de métodos exatas, os tipos de parâmetros e os tipos de retorno definidos na especificação. Se a implementação nativa divergir — retornando `Int` onde a especificação declara `Double`, ou omitindo um campo de uma struct — o compilador nativo rejeita o build. Isso move os erros de tipo dos crashes em runtime para falhas em tempo de compilação. **O que é a API Strict TypeScript e por que ela é importante?** Introduzida no React Native 0.80, a API Strict TypeScript gera os tipos diretamente a partir do código-fonte do React Native, em vez de manter arquivos `.d.ts` escritos manualmente. Ela restringe as importações ao pacote raiz `react-native`, depreciando importações profundas. Isso define uma superfície de API pública estável — refatorações internas não podem quebrar o código do consumidor se este utilizar apenas tipos estrictos. A ativação é feita via `"types": ["react-native/types/strict"]` no `tsconfig.json`. **Como tipar os parâmetros do React Navigation através de navegadores aninhados?** Define-se um tipo `ParamList` por navegador e compõem-se usando `NavigatorScreenParams`. Para um navegador de abas aninhado dentro de uma pilha, a lista de parâmetros da pilha referencia a das abas: `type RootStack = { Main: NavigatorScreenParams; Modal: { id: string } }`. Cada chamada `navigate()` é verificada através de toda a hierarquia de aninhamento, capturando nomes de tela errados ou parâmetros ausentes em tempo de compilação. **Qual problema as uniões discriminadas resolvem no gerenciamento de estado do React Native?** As uniões discriminadas modelam estados mutuamente exclusivos (carregamento, erro, carregado) como branches separados de um tipo union, indexados por um campo `status`. O TypeScript restringe o tipo em cada branch de um switch, de modo que acessar `state.data` só é possível quando `state.status === 'loaded'`. Isso previne estados impossíveis como um indicador de carregamento sendo exibido junto com dados de erro — uma classe de bugs que campos opcionais e flags booleanos não conseguem prevenir. **Explicar a diferença entre TurboModules e o antigo sistema de Native Modules.** Os Native Modules se comunicavam através da bridge assíncrona, serializando todos os dados em JSON. Os TurboModules utilizam JSI (JavaScript Interface) para chamadas C++ diretas e síncronas — sem overhead de serialização. Eles também carregam de forma lazy (no primeiro uso em vez da inicialização do app, reduzindo o tempo de cold start) e utilizam o Codegen para gerar interfaces type-safe a partir das especificações TypeScript. O sistema anterior dependia do parsing de `ReadableMap` / `NSDictionary` com coerção de tipos em runtime; os TurboModules impõem os tipos em tempo de compilação. Para mais [perguntas de entrevista React Native](/technologies/react-native/interview-questions/rn-native-modules), o guia detalhado sobre módulos nativos cobre JSI, Fabric e a arquitetura bridgeless em profundidade. ## Conclusão - A API Strict TypeScript (0.80+) restringe as importações à superfície pública estável, prevenindo quebras causadas por mudanças internas — deve ser ativada em cada projeto novo - O Codegen gera as interfaces nativas a partir dos arquivos de especificação TypeScript, movendo os erros de tipo dos crashes em runtime para falhas de compilação na fronteira JS-nativo - Os parâmetros de navegação tipados via `RootStackParamList` e `NativeStackScreenProps` capturam nomes de tela errados e parâmetros ausentes antes da execução da aplicação - As uniões discriminadas modelam os estados de tela como branches mutuamente exclusivos, tornando os estados impossíveis irrepresentáveis no nível do sistema de tipos - Os TurboModules com especificações tipadas substituem o antigo parsing de `ReadableMap` / `NSDictionary`, impondo segurança de tipos completa de JavaScript através de C++ até o código nativo da plataforma - Os hooks de API genéricos com [TanStack Query](https://tanstack.com/query/latest) preservam a inferência de tipos do endpoint ao componente sem casts manuais --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pt/blog/react-native/react-native-typescript-type-safe-architecture