{"id":13360552,"url":"https://github.com/Microsoft/TypeScript-React-Native-Starter","last_synced_at":"2025-03-12T13:31:38.827Z","repository":{"id":20783986,"uuid":"90786476","full_name":"microsoft/TypeScript-React-Native-Starter","owner":"microsoft","description":"A starter template for TypeScript and React Native with a detailed README describing how to use the two together.","archived":true,"fork":false,"pushed_at":"2022-08-31T15:21:41.000Z","size":249,"stargazers_count":1902,"open_issues_count":43,"forks_count":210,"subscribers_count":39,"default_branch":"master","last_synced_at":"2025-03-04T17:56:09.125Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-09T19:57:43.000Z","updated_at":"2025-03-04T14:37:35.000Z","dependencies_parsed_at":"2022-07-23T15:16:20.619Z","dependency_job_id":null,"html_url":"https://github.com/microsoft/TypeScript-React-Native-Starter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FTypeScript-React-Native-Starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FTypeScript-React-Native-Starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FTypeScript-React-Native-Starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2FTypeScript-React-Native-Starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/TypeScript-React-Native-Starter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243226225,"owners_count":20257045,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-29T22:01:00.912Z","updated_at":"2025-03-12T13:31:38.512Z","avatar_url":"https://github.com/microsoft.png","language":"Objective-C","readme":"# TypeScript React Native Starter\n\n## Prerequisites\n\nBecause you might be developing on one of several different platforms, targeting several different types of devices, basic setup can be involved.\nYou should first ensure that you can run a plain React Native app without TypeScript.\nFollow [the instructions on the React Native website to get started](https://facebook.github.io/react-native/docs/getting-started.html).\nWhen you've managed to deploy to a device or emulator, you'll be ready to start a TypeScript React Native app.\n\nYou will also need [Node.js](https://nodejs.org/en/), [NPM](https://www.npmjs.com), and [Yarn](https://yarnpkg.com/lang/en).\n\n## Initializing\n\nOnce you've tried scaffolding out an ordinary React Native project, you'll be ready to start adding TypeScript.\nLet's go ahead and do that.\n\n```sh\nreact-native init MyAwesomeProject\ncd MyAwesomeProject\n```\n\n## Adding TypeScript\n\nThe next step is to add TypeScript to your project.\nThe following commands will:\n\n* add TypeScript to your project\n* add [React Native TypeScript Transformer](https://github.com/ds300/react-native-typescript-transformer) to your project\n* initialize an empty TypeScript config file, which we'll configure next\n* add an empty React Native TypeScript Transformer config file, which we'll configure next\n* Adds [typings](https://github.com/DefinitelyTyped/DefinitelyTyped) for React and React Native\n\nOkay let's go ahead and run these.\n\n```sh\nyarn add --dev typescript\nyarn add --dev react-native-typescript-transformer\nyarn tsc --init --pretty --jsx react-native\ntouch rn-cli.config.js\nyarn add --dev @types/react @types/react-native\n```\n\nThe `tsconfig.json` file contains all the settings for the TypeScript compile.\nThe defaults created by the command above are mostly fine, but open the file and uncomment the following line:\n\n```js\n{\n  ...\n  // \"allowSyntheticDefaultImports\": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n  ...\n}\n```\n\nThe `rn-cli.config.js` contains the settings for the React Native TypeScript Transformer.\nOpen it and add the following:\n\n```js\nmodule.exports = {\n  getTransformModulePath() {\n    return require.resolve(\"react-native-typescript-transformer\");\n  },\n  getSourceExts() {\n    return [\"ts\", \"tsx\"];\n  }\n};\n```\n\n## Migrating to TypeScript\n\nRename the generated `App.js` and `__tests__/App.js` files to `App.tsx`. `index.js` needs to use the `.js` extension.\nAll new files should use the `.tsx` extension (or `.ts` if the file doesn't contain any JSX).\n\nIf you try to run the app now, you'll get an error like `object prototype may only be an object or null`.\nThis is caused by a failure to import the default export from React as well as a named export on the same line.\nOpen `App.tsx` and modify the import at the top of the file:\n\n```diff\n-import React, { Component } from 'react'\n+import React from 'react'\n+import { Component } from 'react'\n```\n\nSome of this has to do with differences in how Babel and TypeScript interoperate with CommonJS modules.\nIn the future, the two will stabilize on the same behavior.\n\nAt this point, you should be able to run the React Native app.\n\n## Adding TypeScript Testing Infrastructure\n\nSince we're using [Jest](https://github.com/facebook/jest), we'll want to add [ts-jest](https://www.npmjs.com/package/ts-jest) to our devDependencies.\n\n```sh\nyarn add --dev ts-jest\n```\n\nThen, we'll open up our `package.json` and replace the `jest` field with the following:\n\n```json\n\"jest\": {\n  \"preset\": \"react-native\",\n  \"moduleFileExtensions\": [\n    \"ts\",\n    \"tsx\",\n    \"js\"\n  ],\n  \"transform\": {\n    \"^.+\\\\.(js)$\": \"\u003crootDir\u003e/node_modules/babel-jest\",\n    \"\\\\.(ts|tsx)$\": \"\u003crootDir\u003e/node_modules/ts-jest/preprocessor.js\"\n  },\n  \"testRegex\": \"(/__tests__/.*|\\\\.(test|spec))\\\\.(ts|tsx|js)$\",\n  \"testPathIgnorePatterns\": [\n    \"\\\\.snap$\",\n    \"\u003crootDir\u003e/node_modules/\"\n  ],\n  \"cacheDirectory\": \".jest/cache\"\n}\n```\n\nThis will configure Jest to run `.ts` and `.tsx` files with `ts-jest`.\n\n## Installing Type Declaration Dependencies\n\nTo get the best experience in TypeScript, we want the type-checker to understand the shape and API of our dependencies.\nSome libraries will publish their packages with `.d.ts` files (also called \"typed declaration\" or \"type definition\" files) which can describe the shape of the underlying JavaScript.\nFor other libraries, we'll need to explicitly install the appropriate package in the `@types/` npm scope.\n\nFor example, here we'll need types for Jest, React, and React Native, and React Test Renderer.\n\n```ts\nyarn add --dev @types/jest @types/react @types/react-native @types/react-test-renderer\n```\n\nWe saved these declaration file packages to our _dev_ dependencies because we're not publishing this package as a library to npm.\nIf we were, we might have to add some of them as regular dependencies.\n\nYou can read more [here about getting `.d.ts` files](https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html).\n\n## Ignoring More Files\n\nFor your source control, you'll want to start ignoring the `.jest` folder.\nIf you're using git, we can just add entries to our `.gitignore` file.\n\n```config\n# Jest\n#\n.jest/\n```\n\nAs a checkpoint, consider committing your files into version control.\n\n```sh\ngit init\ngit add .gitignore # import to do this first, to ignore our files\ngit add .\ngit commit -am \"Initial commit.\"\n```\n\n## Adding a Component\n\nWe can now add a component to our app.\nLet's go ahead and create a `Hello.tsx` component.\nCreate a `components` directory and add the following example.\n\n```ts\n// components/Hello.tsx\nimport React from \"react\"\nimport { Button, StyleSheet, Text, View } from \"react-native\"\n\nexport interface Props {\n  name: string\n  enthusiasmLevel?: number\n  onIncrement?: () =\u003e void\n  onDecrement?: () =\u003e void\n}\n\ninterface State {\n  enthusiasmLevel: number\n}\n\nexport class Hello extends React.Component\u003cProps, State\u003e {\n  constructor(props: Props) {\n    super(props)\n\n    if ((props.enthusiasmLevel || 0) \u003c= 0) {\n      throw new Error(\"You could be a little more enthusiastic. :D\")\n    }\n\n    this.state = {\n      enthusiasmLevel: props.enthusiasmLevel || 1\n    }\n  }\n\n  onIncrement = () =\u003e this.setState({ enthusiasmLevel: this.state.enthusiasmLevel + 1 });\n  onDecrement = () =\u003e this.setState({ enthusiasmLevel: Math.max(0, this.state.enthusiasmLevel - 1) });\n  getExclamationMarks = (numChars: number) =\u003e Array(numChars + 1).join(\"!\")\n\n  render() {\n    return (\n      \u003cView style={styles.root}\u003e\n        \u003cText style={styles.greeting}\u003e\n          Hello {this.props.name + this.getExclamationMarks(this.state.enthusiasmLevel)}\n        \u003c/Text\u003e\n\n        \u003cView style={styles.buttons}\u003e\n          \u003cView style={styles.button}\u003e\n            \u003cButton\n              title=\"-\"\n              onPress={this.onDecrement}\n              accessibilityLabel=\"decrement\"\n              color=\"red\"\n            /\u003e\n          \u003c/View\u003e\n\n          \u003cView style={styles.button}\u003e\n            \u003cButton\n              title=\"+\"\n              onPress={this.onIncrement}\n              accessibilityLabel=\"increment\"\n              color=\"blue\"\n            /\u003e\n          \u003c/View\u003e\n        \u003c/View\u003e\n      \u003c/View\u003e\n    )\n  }\n}\n\n// styles\n\nconst styles = StyleSheet.create({\n  root: {\n    alignItems: \"center\",\n    alignSelf: \"center\"\n  },\n  buttons: {\n    flexDirection: \"row\",\n    minHeight: 70,\n    alignItems: \"stretch\",\n    alignSelf: \"center\",\n    borderWidth: 5\n  },\n  button: {\n    flex: 1,\n    paddingVertical: 0\n  },\n  greeting: {\n    color: \"#999\",\n    fontWeight: \"bold\"\n  }\n})\n```\n\nWhoa! That's a lot, but let's break it down:\n\n* Instead of rendering HTML elements like `div`, `span`, `h1`, etc., we're rendering components like `View` and `Button`.\n  These are native components that work across different platforms.\n* Styling is specified using the `StyleSheet.create` function that React Native gives us.\n  React's StyleSheets allow us to control our layout using Flexbox, and style using other constructs similar to those in CSS stylesheets.\n\n## Adding a Component Test\n\nNow that we've got a component, let's try testing it.\n\nWe already have Jest installed as a test runner.\nWe're going to write snapshot tests for our components, let's add the required add-on for snapshot tests:\n\n```sh\nyarn add --dev react-addons-test-utils\n```\n\nNow let's create a `__tests__` folder in the `components` directory and add a test for `Hello.tsx`:\n\n```ts\n// components/__tests__/Hello.tsx\nimport React from 'react'\nimport renderer from 'react-test-renderer'\n\nimport { Hello } from \"../Hello\"\n\nit(\"renders correctly with defaults\", () =\u003e {\n  const button = renderer.create(\u003cHello name=\"World\" enthusiasmLevel={1} /\u003e).toJSON()\n  expect(button).toMatchSnapshot()\n})\n```\n\nThe first time the test is run, it will create a snapshot of the rendered component and store it in the `components/__tests__/__snapshots__/Hello.tsx.snap` file.\nWhen you modify your component, you'll need to update the snapshots and review the update for inadvertent changes.\nYou can read more about testing React Native components [here](https://facebook.github.io/jest/docs/en/tutorial-react-native.html).\n\n## Next Steps\n\nCheck out [our React TypeScript tutorial](https://github.com/Microsoft/TypeScript-React-Starter) where we also cover topics like state management with [Redux](http://redux.js.org).\nThese same subjects can be applied when writing React Native apps.\n\nAdditionally, you may want to look at the [ReactXP](https://microsoft.github.io/reactxp/) if you're looking for a component library written entirely in TypeScript that supports both React on the web as well as React Native.\n\n## Helpful Resources\n\n* [Create React Native TypeScript](https://github.com/mathieudutour/create-react-native-app-typescript) is a port of [Create React Native App](https://github.com/react-community/create-react-native-app) that uses TypeScript.\n* [React Native Template TypeScript](https://github.com/emin93/react-native-template-typescript) is a clean and minimalist template for a quick start with TypeScript.\n","funding_links":[],"categories":["Reference","TypeScript Starter/Boilerplate"],"sub_categories":["3. use `styled-components` (ts)","英文资源"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMicrosoft%2FTypeScript-React-Native-Starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMicrosoft%2FTypeScript-React-Native-Starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMicrosoft%2FTypeScript-React-Native-Starter/lists"}