# TypeScript-React-Starter
**Repository Path**: bronson/TypeScript-React-Starter
## Basic Information
- **Project Name**: TypeScript-React-Starter
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-06-22
- **Last Updated**: 2021-06-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
This repo is now deprecated. In the time since it created [TypeScript support](https://facebook.github.io/create-react-app/docs/adding-typescript) is now a default feature of [Create React App](https://facebook.github.io/create-react-app/), [Next.JS](https://nextjs.org) and [Razzle](https://github.com/jaredpalmer/razzle).
This means you can get started with:
```sh
# Creates an app called my-app
npx create-react-app my-app --typescript
cd my-app
# Adds the type definitions
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
echo "Good to go :tada:"
```
This repo offers some exmples on how to take that project into production and handle testing and state. However, you can
also use the official documentation in the Create React App website for that.
If you'd like to know more about how to effectively do React with TypeScript, we recommend looking at the following:
- [React+TypeScript Cheatsheets](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#reacttypescript-cheatsheets)
- [React & Redux in TypeScript - Static Typing Guide](https://github.com/piotrwitek/react-redux-typescript-guide#react--redux-in-typescript---static-typing-guide)
- [Use TypeScript to develop React applications](https://egghead.io/courses/use-typescript-to-develop-react-applications)
- [Ultimate React Component Patterns with Typescript 2.8](https://levelup.gitconnected.com/ultimate-react-component-patterns-with-typescript-2-8-82990c516935)
Below is the original README for this sample.
---
# TypeScript React Starter
This quick start guide will teach you how to wire up TypeScript with [React](http://facebook.github.io/react/).
By the end, you'll have
* a project with React and TypeScript
* linting with [TSLint](https://github.com/palantir/tslint)
* testing with [Jest](https://facebook.github.io/jest/) and [Enzyme](http://airbnb.io/enzyme/), and
* state management with [Redux](https://github.com/reactjs/react-redux)
We'll use the [create-react-app](https://github.com/facebookincubator/create-react-app) tool to quickly get set up.
We assume that you're already using [Node.js](https://nodejs.org/) with [npm](https://www.npmjs.com/).
You may also want to get a sense of [the basics with React](https://facebook.github.io/react/docs/hello-world.html).
# Install create-react-app
We're going to use the create-react-app because it sets some useful tools and canonical defaults for React projects.
This is just a command-line utility to scaffold out new React projects.
```shell
npm install -g create-react-app
```
# Create our new project
We'll create a new project called `my-app`:
```shell
create-react-app my-app --scripts-version=react-scripts-ts
```
[react-scripts-ts](https://www.npmjs.com/package/react-scripts-ts) is a set of adjustments to take the standard create-react-app project pipeline and bring TypeScript into the mix.
At this point, your project layout should look like the following:
```text
my-app/
├─ .gitignore
├─ images.d.ts
├─ node_modules/
├─ public/
├─ src/
│ └─ ...
├─ package.json
├─ tsconfig.json
├─ tsconfig.prod.json
├─ tsconfig.test.json
└─ tslint.json
```
Of note:
* `tsconfig.json` contains TypeScript-specific options for our project.
* We also have a `tsconfig.prod.json` and a `tsconfig.test.json` in case we want to make any tweaks to our production builds, or our test builds.
* `tslint.json` stores the settings that our linter, [TSLint](https://github.com/palantir/tslint), will use.
* `package.json` contains our dependencies, as well as some shortcuts for commands we'd like to run for testing, previewing, and deploying our app.
* `public` contains static assets like the HTML page we're planning to deploy to, or images. You can delete any file in this folder apart from `index.html`.
* `src` contains our TypeScript and CSS code. `index.tsx` is the entry-point for our file, and is mandatory.
* `images.d.ts` will tell TypeScript that certain types of image files can be `import`-ed, which create-react-app supports.
# Setting up source control
Our testing tool, Jest, expects some form of source control (such as Git or Mercurial) to be present.
For it to run correctly, we'll need to initialize a git repository.
```sh
git init
git add .
git commit -m "Initial commit."
```
> Note: if you've cloned this repository, you won't have to run the above at all.
# Overriding defaults
The TSLint configuration that react-scripts-ts sets us up with is a bit overzealous.
Let's fix that up.
```diff
{
- "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
+ "extends": [],
+ "defaultSeverity": "warning",
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts"
]
}
}
```
[Configuring TSLint](https://palantir.github.io/tslint/usage/configuration/) is out of the scope of this starter, but you should feel free to experiment with something that works for you.
# Running the project
Running the project is as simple as running
```sh
npm run start
```
This runs the `start` script specified in our `package.json`, and will spawn off a server which reloads the page as we save our files.
Typically the server runs at `http://localhost:3000`, but should be automatically opened for you.
This tightens the iteration loop by allowing us to quickly preview changes.
# Testing the project
Testing is also just a command away:
```sh
npm run test
```
This command runs Jest, an incredibly useful testing utility, against all files whose extensions end in `.test.ts` or `.spec.ts`.
Like with the `npm run start` command, Jest will automatically run as soon as it detects changes.
If you'd like, you can run `npm run start` and `npm run test` side by side so that you can preview changes and test them simultaneously.
# Creating a production build
When running the project with `npm run start`, we didn't end up with an optimized build.
Typically, we want the code we ship to users to be as fast and small as possible.
Certain optimizations like minification can accomplish this, but often take more time.
We call builds like this "production" builds (as opposed to development builds).
To run a production build, just run
```sh
npm run build
```
This will create an optimized JS and CSS build in `./build/static/js` and `./build/static/css` respectively.
You won't need to run a production build most of the time,
but it is useful if you need to measure things like the final size of your app.
# Creating a component
We're going to write a `Hello` component.
The component will take the name of whoever we want to greet (which we'll call `name`), and optionally, the number of exclamation marks to trail with (`enthusiasmLevel`).
When we write something like ``, the component should render to something like `
Hello Daniel!!!
`.
If `enthusiasmLevel` isn't specified, the component should default to showing one exclamation mark.
If `enthusiasmLevel` is `0` or negative, it should throw an error.
We'll write a `Hello.tsx`:
```ts
// src/components/Hello.tsx
import * as React from 'react';
export interface Props {
name: string;
enthusiasmLevel?: number;
}
function Hello({ name, enthusiasmLevel = 1 }: Props) {
if (enthusiasmLevel <= 0) {
throw new Error('You could be a little more enthusiastic. :D');
}
return (
);
}
export default Hello;
// helpers
function getExclamationMarks(numChars: number) {
return Array(numChars + 1).join('!');
}
```
Notice that we defined a type named `Props` that specifies the properties our component will take.
`name` is a required `string`, and `enthusiasmLevel` is an optional `number` (which you can tell from the `?` that we wrote out after its name).
We also wrote `Hello` as a stateless function component (an SFC).
To be specific, `Hello` is a function that takes a `Props` object, and picks apart (or "destructures") all the properties that it will be passed.
If `enthusiasmLevel` isn't given in our `Props` object, it will default to `1`.
Writing functions is one of two primary [ways React allows us to make components]((https://facebook.github.io/react/docs/components-and-props.html#functional-and-class-components)).
If we wanted, we *could* have written it out as a class as follows:
```ts
class Hello extends React.Component {
render() {
const { name, enthusiasmLevel = 1 } = this.props;
if (enthusiasmLevel <= 0) {
throw new Error('You could be a little more enthusiastic. :D');
}
return (
);
}
}
```
Classes are useful [when our component instances have some state or need to handle lifecycle hooks](https://facebook.github.io/react/docs/state-and-lifecycle.html).
But we don't really need to think about state in this specific example - in fact, we specified it as `object` in `React.Component`, so writing an SFC makes more sense here, but it's important to know how to write a class component.
Notice that the class extends `React.Component`.
The TypeScript-specific bit here are the type arguments we're passing to `React.Component`: `Props` and `object`.
Here, `Props` is the type of our class's `this.props`, and `object` is the type of `this.state`.
We'll return to component state in a bit.
Now that we've written our component, let's dive into `index.tsx` and replace our render of `` with a render of ``.
First we'll import it at the top of the file:
```ts
import Hello from './components/Hello';
```
and then change up our `render` call:
```ts
ReactDOM.render(
,
document.getElementById('root') as HTMLElement
);
```
## Type assertions
One thing we'll point out in this section is the line `document.getElementById('root') as HTMLElement`.
This syntax is called a *type assertion*, sometimes also called a *cast*.
This is a useful way of telling TypeScript what the real type of an expression is when you know better than the type checker.
The reason we need to do so in this case is that `getElementById`'s return type is `HTMLElement | null`.
Put simply, `getElementById` returns `null` when it can't find an element with a given `id`.
We're assuming that `getElementById` will actually succeed, so we need to convince TypeScript of that using the `as` syntax.
TypeScript also has a trailing "bang" syntax (`!`), which removes `null` and `undefined` from the prior expression.
So we *could* have written `document.getElementById('root')!`, but in this case we wanted to be a bit more explicit.
## Stateful components
We mentioned earlier that our component didn't need state.
What if we wanted to be able to update our components based on user interaction over time?
At that point, state becomes more important.
Deeply understanding best practices around component state in React are out of the scope of this starter, but let's quickly peek at a *stateful* version of our `Hello` component to see what adding state looks like.
We're going to render two `