TypeScript in a generated project is a checking layer, and nothing in the build runs it.
TypeScript in a React Native and Expo project is type annotations in your source files plus one short configuration file, and the app ships whether or not those annotations are correct. React Native's own documentation says TypeScript sources are transformed by Babel during bundling, and recommends using the TypeScript compiler only for type checking. Babel strips the types out and moves on. Metro produces the bundle. The simulator opens. A project carrying forty type errors installs and runs exactly like one carrying none. That single fact decides how much attention any of this deserves in a codebase you did not type, and it is the part nobody tells you when they hand the project over. It also belongs in your picture of what an app costs to maintain.
What follows is which files the generator wrote, which ones the Expo command line tool rewrites behind your back, which parts of the project the type checker never looks at, and what it costs you when nobody runs it. Every path, flag and file name below comes from React Native's and Expo's own documentation, read on 17 October 2026.
See where each file came fromThe short version
The build does not check your types. Only a command you run does.
Two separate tools read your source files, and most people assume they are one tool. The bundler turns your files into something a phone can run. The type checker reads the same files and complains. The bundler never calls the type checker, and nothing connects them. This is deliberate and it is written down: React Native recommends using the TypeScript compiler only for type checking, because Babel is already doing the transform.
So in a handed-over project there are exactly three questions worth your time. Which files did the generator write and which are yours. Whether anything in your workflow actually runs the checker, because by default nothing does. And how strict the config is, because that is a single line and it changes how much the checker will tell you. The rest of TypeScript is a language you can learn later, or never, depending on how much of this code you plan to edit by hand.
What is TypeScript actually doing in a project you did not write?
It is annotating what each value is supposed to be, so a tool can tell you when two parts of the app disagree. A screen expects a customer record with a phone number on it. The function that fetches customers returns one without. In plain JavaScript you find that out when a customer taps the button. With types declared, the checker finds it while you are still editing. That is the whole trade: you write a little more, and a class of mistake stops reaching the phone.
This is the default rather than a choice somebody made for you. React Native's documentation states that new React Native projects target TypeScript by default, and that projects created by its command line tool or by popular templates will use TypeScript. Expo maintains TypeScript templates and will offer to install and configure TypeScript if a .ts or .tsx file appears in a project that does not have it yet. Nobody picked this for your app in particular. It is simply what a new React Native project is now.
What surprises people is how little the types are involved in running the app. The compiler in a React Native project is not producing your JavaScript. Babel is. The TypeScript compiler is configured to emit nothing at all: the published base config sets noEmit to true, so running it produces a list of complaints and not a single output file. Babel's own plugin documentation is blunt about the other half, saying the plugin does not add the ability to type-check the JavaScript passed to it. Two tools, one job each, no connection between them.
The practical consequence is worth saying slowly, because it is the opposite of how most compiled languages behave. A type error is not a build failure. It is a note in a report that nobody is obliged to read. Your editor will underline it in red while you have the file open, and the moment you close the file the error is as invisible as it was before. There is no gate anywhere in the path from your keyboard to a customer's phone that stops on it.
React Native, using TypeScript, page last updated 12 August 2026, read 17 October 2026
Which of these files did the generator write, and which are yours?
Start with tsconfig.json, because it is short and it is the only one you own outright. Expo's guide says a project's tsconfig.json should extend expo/tsconfig.base by default, and that you can produce one by running npx expo customize tsconfig.json. The published base config, read on 17 October 2026, is a short file and worth reading once. It sets noEmit, allowJs, skipLibCheck, resolveJsonModule, the react-jsx transform, bundler module resolution and a react-native condition. It excludes node_modules, babel.config.js, metro.config.js, jest.config.js, and the android and ios directories.
Two of those exclusions matter in a project you inherited. Native code is outside the type checker entirely, so if someone promised you that TypeScript covers the whole app, it does not: it stops at the edge of ios and android. And skipLibCheck means type errors inside your dependencies are not reported, which is usually a mercy and occasionally the reason a real incompatibility stays quiet during an upgrade. Neither is a problem. Both are things to know before you trust a clean run.
Then there are the files you must not touch. Expo's documentation on typed routes says the command line tool generates expo-env.d.ts in the project root, git-ignores it, adds it to tsconfig.json, and that it should not be removed or changed at any time. It also says the include list needs an entry for the hidden .expo directory, and that those entries are required and should not be removed. If you have ever seen a project where somebody tidied the include array and the type check started failing on imports that obviously exist, this is why. The typed routes feature itself was documented as beta and not enabled by default when that page was last updated on 28 February 2026, so check your own app config rather than assuming.
The last category is the one that creates arguments later: paths. Expo says its command line tool supports path aliases in tsconfig.json automatically, and that the feature is on by default and can be switched off in the app config. React Native without Expo does not work that way. Its documentation has you declare the same aliases twice, once in tsconfig.json for the type checker and once in babel.config.js through a resolver plugin for the bundler. If an import resolves in your editor and fails at runtime, or the reverse, that split is the first place to look.
Expo, TypeScript guide, page last updated 16 October 2026, read 17 October 2026
Check yours
Who wrote this file, and what do you do with it
Tick anything you can see in your project. The answer says whether it is generated, whether it belongs in git, and whether the type checker reads it at all.
Nothing ticked. Open the project root and start with tsconfig.json. It is one short file and it decides everything else on this page.
Do you have to care if the app already runs?
If you never open the code again, no. A shipped build does not degrade because its types went stale. The reason to care is that you are going to change something, and the type checker is the cheapest review you will ever get on a codebase nobody on your side wrote. Rename a field in one place and it tells you about the eleven other places that used the old name. That is not a style preference. On an inherited project it is most of the value.
The second reason is specific to how React Native apps reach people. A JavaScript change can go out as one of the over the air updates rather than as a new store build, which means no review and no waiting. That is the right thing for small fixes and it also removes the last human being who might have looked at the change. When nothing between your editor and the phone is a gate, the only gate left is one you run yourself.
So find out whether anything runs it today. Open package.json and look at the scripts. Expo's guide shows the type check as a package manager script, for example npm run tsc, which quietly assumes somebody added a script called tsc. Expo's own default template, read on 17 October 2026, ships scripts for start, android, ios, web, lint and a project reset, and no tsc. The lint script checks lint rules, which are a different thing from types. If your project looks like that, then right now nothing checks your types except whichever editor happens to be open.
Wiring it up is one line in package.json and one step in whatever runs your builds. The piece people miss is that some of the types are generated rather than written, and generation happens when the development server starts. On a laptop that is constant. On a build runner it never happens at all, so the check fails there on files that are fine locally. Expo's documented answer for that case is to run npx expo customize tsconfig.json first, which regenerates what the dev server would have.
What does leaving it alone actually cost?
It costs you the ability to turn it back on cheaply. Type errors accumulate quietly because nothing fails, and the bill arrives all at once on the day somebody decides to run the check. Thirty errors is an afternoon. Four hundred is a project, and it lands at the worst possible moment, which is usually the moment you are trying to do something else urgently.
The same arithmetic applies to the strict setting, and this is where you should look first. The published expo/tsconfig.base does not set strict. Expo's guide describes the default configuration as user-friendly and says to enable strict yourself under compilerOptions if you want tighter checking. Expo's own default template does turn it on. So the honest answer to whether your project is strict is that it depends entirely on the file sitting in your root directory, and you have to open it. Turning strict on in month one is a quiet change. Turning it on in month twelve is a negotiation.
The bill most people actually meet, though, is an SDK upgrade. Types ship with the libraries, so when the libraries move, the types move with them, and a clean type check is how you find out what changed before your customers do. If the project has drifted, the upgrade and a backlog of unrelated errors arrive in the same pull request and nobody can tell which is which. Read the Expo SDK release notes before an upgrade, then run the checker before and after so you can attribute every new error to something.
There is one cost that is not technical. If you ever hand the project to a contractor or an agency, the first thing a competent one does is run the type check, and what it prints is their opening estimate of how much of this code they can trust. A clean run on a generated project reads as a project somebody has been looking after. A screen full of errors reads as a rewrite, whether or not it is one. That judgement is made in the first ten minutes and it is hard to argue with afterwards.
Expo, TypeScript guide, on the base configuration and enabling strict mode, read 17 October 2026
What reads your types, and what stops on an error
Six things in a normal project touch your source files. Exactly one of them will refuse to continue because a type is wrong, and it is the one that only runs when somebody types the command.
| What runs | What it reads | Stops on a type error |
|---|---|---|
| Metro and Babel, every time the app builds | Your .ts and .tsx files, with the types stripped out | No |
| tsc, run by hand | Everything listed in the include array of tsconfig.json | Yes |
| The lint script the template ships | Lint rules, not types | No |
| Expo CLI when the dev server starts | Rewrites the generated declaration files | No |
| Your editor | The same files tsc reads | Shows them, blocks nothing |
| App Store and Google Play review | A compiled binary with no types left in it | No |
Where this lands if a builder generated your app
Newly is an AI app builder. You describe an app in plain English and it writes a real React Native and Expo project in TypeScript that you own, with two-way GitHub sync, so the tsconfig.json and the .tsx files described above are in a repository you can clone. It uploads iOS builds to TestFlight, publishes to Google Play internal testing and builds a standalone Android APK. It does not submit to the App Store for you, because Apple requires the provider of the app's content to submit. It is $25 a month and there is no free plan. If the words React Native and Expo are new to you, start with what React Native is and come back.
Generation changes one thing about this subject and leaves the rest alone. The thing it changes is the starting point: a generated project arrives with the types already written, which is the part people find tedious and therefore skip. Nobody has to be talked into annotating a function they have not written yet. You begin from a project that would pass its own check, which is a better position than most hand-built projects reach in their first month.
What it does not change is everything after that. The checker is still a command somebody has to run, the generated declaration files still regenerate from the development server and not from your build runner, and strict is still one line in a file you own. The moment you or anyone else edits a screen by hand, the project is as clean or as messy as whoever is watching it. That is not a gap in the tool. No builder can keep a type check green in a codebase other people are editing, and any that claims to is describing something else.
Questions people ask about TypeScript in a generated project
Normally yes, because the framework defaults to it. React Native's own documentation says new React Native projects target TypeScript by default, and that projects created by the React Native CLI or popular templates will use TypeScript by default. Expo ships a default template with TypeScript already configured, and its SDK's JavaScript interface is itself written in TypeScript. So a generated Expo project arrives with .tsx screens, a tsconfig.json, and typescript and @types/react as dev dependencies. Read 17 October 2026.
Open tsconfig.json, then run the check once
Two jobs, both small. Read your own tsconfig.json, which is a short file, so you know whether strict is on. Then run the compiler once and write the number down, because that number is your baseline and every later argument about this project is really an argument about which direction it moved.
Start building