1--- 2title: Using TypeScript 3description: An in-depth guide on configuring an Expo project with TypeScript. 4--- 5 6import { Terminal } from '~/ui/components/Snippet'; 7 8> Example project: [with-typescript](https://github.com/expo/examples/tree/master/with-typescript) 9 10Expo has first-class support for [TypeScript](https://www.typescriptlang.org/). The JavaScript interface of the Expo SDK is completely written in TypeScript. 11 12To get started, create a **tsconfig.json** in your project root: 13 14<Terminal cmd={['$ touch tsconfig.json']} /> 15 16Running `npx expo start` will prompt you to install the required dependencies (`typescript`, `@types/react`, `@types/react-native`), and automatically configure your **tsconfig.json**. 17 18Rename files to convert them to TypeScript. For example, you would rename **App.js** to **App.tsx**. Use the **.tsx** extension if the file includes React components (JSX). If the file did not include any JSX, you can use the **.ts** file extension. 19 20<Terminal cmd={['$ mv App.js App.tsx']} /> 21 22You can now run `yarn tsc` or `npx tsc` to typecheck the project. 23 24## Base configuration 25 26> You can disable the TypeScript setup in Expo CLI with the environment variable `EXPO_NO_TYPESCRIPT_SETUP=1` 27 28A project's **tsconfig.json** should extend the `expo/tsconfig.base` by default. This sets the following default [compiler options][tsc-compileroptions] (which can be overwritten in your project's **tsconfig.json**): 29 30- `"allowJs"`: `true` 31 - Allow JavaScript files to be compiled. If you project requires more strictness, you can disable this. 32- `"esModuleInterop"`: `true` 33 - Improve Babel ecosystem compatibility. This also sets `allowSyntheticDefaultImports` to `true`, allowing default imports from modules with no default export. 34- [`"jsx"`][tsc-jsx]: `"react-native"` 35 - Preserve JSX, and converts the `jsx` extension to `js`. This is optimized for bundlers that transform the JSX internally (like Metro). 36- `"lib"`: `["DOM", "ESNext"]` 37 - Allow using the latest [ECMAScript proposed features and libraries](https://github.com/tc39/proposals). 38- [`"moduleResolution"`][tsc-moduleresolution]: `"node"` 39 - Emulate how Metro and webpack resolve modules. 40- `"noEmit"`: `true` 41 - Only use the TypeScript compiler (TSC) to check the code. The Metro bundler is responsible for compiling TypeScript to JavaScript. 42- `"resolveJsonModule"`: `true` 43 - Enables importing **.json** files. Metro's default behavior is to allow importing json files as JS objects. 44- `"skipLibCheck"`: `true` 45 - Skip type checking of all declaration files (`*.d.ts`). 46- `"target"`: `"ESNext"` 47 - Compile to the latest version of ECMAScript. 48 49[tsc-jsx]: https://www.typescriptlang.org/docs/handbook/jsx.html 50[tsc-compileroptions]: https://www.typescriptlang.org/docs/handbook/compiler-options.html 51[tsc-moduleresolution]: https://www.typescriptlang.org/docs/handbook/module-resolution.html 52 53## Project configuration 54 55Expo CLI will automatically modify your **tsconfig.json** to the preferred default which is optimized for universal React development: 56 57```json 58{ 59 "extends": "expo/tsconfig.base", 60 "compilerOptions": {} 61} 62``` 63 64The default configuration is forgiving and makes it easier to adopt TypeScript. If you'd like to opt-in to more strict type checking, you can add `"strict": true` to the `compilerOptions`. We recommend enabling this to minimize the chance of introducing runtime errors. 65 66Certain language features may require additional configuration, for example if you'd like to use decorators you will need to add the `experimentalDecorators` option. For more information on the available properties see the [TypeScript compiler options documentation](https://www.typescriptlang.org/docs/handbook/compiler-options.html) documentation. 67 68## Starting from scratch: using a TypeScript template 69 70<Terminal 71 cmd={['$ npx create-expo-app -t expo-template-blank-typescript']} 72 cmdCopy="npx create-expo-app -t expo-template-blank-typescript" 73/> 74 75The easiest way to get started is to initialize your new project using a TypeScript template, then run `yarn tsc` or `npx tsc` to "typecheck" the project. 76 77When you create new source files in your project you should use the **.ts** extension or the **.tsx** if the file includes React components. 78 79## TypeScript for config files 80 81You may find that you want to use TypeScript for the config files in your project, like the **webpack.config.js**, **metro.config.js**, or **app.config.js**. These will require a little extra setup. You can utilize the [`ts-node` require hook](https://github.com/TypeStrong/ts-node#programmatic) to _import_ TypeScript files into your JS config file, meaning any import can be TypeScript, but the root file will still need to be JavaScript. 82 83<Terminal cmd={['$ yarn add -D ts-node typescript']} /> 84 85### webpack.config.js 86 87> You may need to install the `@expo/webpack-config` package. 88 89**webpack.config.js** 90 91```js 92require('ts-node/register'); 93module.exports = require('./webpack.config.ts'); 94``` 95 96**webpack.config.ts** 97 98```ts 99import createExpoWebpackConfigAsync from '@expo/webpack-config/webpack'; 100import { Arguments, Environment } from '@expo/webpack-config/webpack/types'; 101 102module.exports = async function (env: Environment, argv: Arguments) { 103 const config = await createExpoWebpackConfigAsync(env, argv); 104 // Customize the config before returning it. 105 return config; 106}; 107``` 108 109### metro.config.js 110 111> Metro doesn't ship types or have a definitely typed package. 112 113**metro.config.js** 114 115```js 116require('ts-node/register'); 117module.exports = require('./metro.config.ts'); 118``` 119 120**metro.config.ts** 121 122```ts 123import { getDefaultConfig } from '@expo/metro-config'; 124 125const defaultConfig = getDefaultConfig(__dirname); 126 127module.exports = defaultConfig; 128``` 129 130### app.config.js 131 132Technically **app.config.ts** is supported by default, but it doesn't support external TypeScript modules, or **tsconfig.json** customization. You can use the following approach to get a more comprehensive TypeScript setup. 133 134**app.config.js** 135 136```js 137require('ts-node/register'); 138module.exports = require('./app.config.ts'); 139``` 140 141**app.config.ts** 142 143```ts 144import { ExpoConfig } from 'expo/config'; 145 146// In SDK 46 and lower, use the following import instead: 147// import { ExpoConfig } from '@expo/config-types'; 148 149const config: ExpoConfig = { 150 name: 'my-app', 151 slug: 'my-app', 152}; 153 154export default config; 155``` 156 157## Learning how to use TypeScript 158 159A good place to start learning TypeScript is the official [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html). 160 161### TypeScript and React components 162 163We recommend reading over and referring to the [React TypeScript CheatSheet](https://github.com/typescript-cheatsheets/react) to learn how to type your React components in a variety of common situations. 164 165### Advanced types 166 167If you would like to go deeper and learn how to create more expressive and powerful types, we recommend the [Advanced Static Types in TypeScript course](https://egghead.io/courses/advanced-static-types-in-typescript) (this requires an egghead.io subscription). 168