React<T> with TypeScript

Owais Ahmed Quershi

github.com/oahmedqureshi

Technical Lead@Sastaticket.pk

oahmed@sastaticket.pk

Introduction to TS

- Let's not be too theoretical

  • 1st Oct, 2012 by Microsoft
  • Superset of JavaScript
  • Adds static type system (but you may skip)
  • JavaScript is valid TypeScript
  • Has absolutely nothing to do with ES-Standards
  • Helps you scale your large-scale apps

    ... So much more

Why bother using it?

best practices apart

Writing ~10%

Modifying

Reading

 ~65%

~25%

Story in the Enterprise apps is different

...continued

  • Maintaining apps is difficult if no documentation
  • It documents your codebase naturally
  • Prevents compile time errors
  • Helps you model your data at its best
  • Cool Intellisense 
  • Now TS has first class JSX support
  • Minimize test cases

Type System

const date: number = Date.now(); // 'number of milliseconds'
const hybrid: boolean | string = 'myname' || false; // false; or 'myname'

type toppings = 'Onion' | 'Pepperoni' | 'Mashroom';

interface Pizza {
    topping?: Array<toppings>,
    cheese: boolean,
}

const BuzzPizza: Pizza = {
    topping: ["Onion"],
    cheese: true
}


interface Burger {
    cheese?: boolean, 
    patty: 'beef' | 'chicken',
    sauces: [sauces, sauces]
}

type sauces = 'mustard' | 'ketchup' | 'bbq';

const bigO: Burger = {
    sauces: ["bbq", "ketchup"],
    patty: 'beef',
}

type Fastfood = Pizza | Burger; // Union Types

const hungerTime: Fastfood = {
    topping: ['Onion'],
    cheese: true,
    sauces: ["bbq", "ketchup"],
    patty: 'chicken'
} 

🤔

But...

  • Learning Curve 
  • A bit more OOP

Initialize your React app with TypeScript

Simplest way with all build configuration: create-react-app-typscript Repository on github

create-react-app <app-name> --scripts-version=react-scripts-ts

CRAT is a fork of CRA that adds the TypeScript compiler to Webpack and configures TSLint instead of ESLint

TSLint Restrictions

import * as React from 'react';
import * as ReactDOM from 'react-dom';
/*
* you can run TypeScript with --allowSyntheticDefaultImports 
*(or add "allowSyntheticDefaultImports": true to tsconfig) to import like in regular jsx:
*/

import React from 'react';
import ReactDOM from 'react-dom';



you can also modify TSLint file:

{
    -"extends": ["tslint:recommended", "tslint-react", "tslint-config-      prettier"],
    +"extends": [],
    +"defaultSeverity": "warning"

}

Specify the type of Props & State of components

Stateless Functional Component:

 

const App = ({ message }: { message: string }) => <div>{message}</div>;
const App: React.SFC<{ message: string }> = ({ message }) => <div>{message}</div>;

 

SFC type that is the alias of StatelessComponent interface.

Stateful Class-based Components

Within TypeScript, React.Component is a generic type (aka React.Component<PropType, StateType>), so you actually want to provide it with prop and (optionally) state types:

interface Iprops {
    message: string
}

interface Istate {
    counter: number
}
class App extends React.Component<Iprops, Istate> {
  state = {
    count: 0
  }
  render() {
    return (
      <div>{this.props.message} {this.state.count}</div>
    );
  }
}

Useful React Type 

export declare interface AppProps {
  children1: JSX.Element; // bad
  children2: JSX.Element | JSX.Element[]; // meh
  children3: React.ReactChild | React.ReactChildren; // better
  children: React.ReactNode; // best
  style?: React.CSSProperties; // for style
  onChange?: (e: React.FormEvent<HTMLInputElement>) => void; // form events!
  props: Props & React.HTMLProps<HTMLButtonElement> // to impersonate all the props of a HTML element
}

Forms and Events

onChange = (e: React.FormEvent<HTMLInputElement>): void => {
  this.setState({text: e.currentTarget.value})
}

Resources

  • https://github.com/oahmedqureshi/react-typescript-count
  • https://github.com/wmonk/create-react-app-typescript
  • https://github.com/Microsoft/TypeScript-React-Starter
  • https://github.com/piotrwitek/react-redux-typescript-guide

That's All Folks.

deck

By oahmedqureshi