React + Typescript = <3

Godefroy de Compreignac

Talk @ React Nantes - 28/06/2018

Avec React tout est Javascript

  • Vues : JSX
  • Style : CSS-in-JS
  • State et logique

Les avantages sont multiples :

  • Contrôle total par l'IDE et le linter
  • 1 syntaxe unique
  • 1 fichier par composant

Le point noir pour beaucoup :

Javascript !

const subFamilyId = state.productReducer.products
  .entries[id].infos
  .subFamilies[0].id

(tiré d'un vrai projet client)

Javascript est

faiblement typé et laxiste

Des solutions existent :

  • Typescript
  • Flow
  • ReasonML
  • Elm...

Typescript = Javascript + types

  • Apprentissage rapide
  • Compatible JS legacy
  • Avantages immédiats

On peut comparer Typescript

à Babel + Flow sous stéroïdes

Analyse statique du code

Transpilation

Check dans l'éditeur et à la compilation
🡺  Moins d'erreurs au runtime

Vers Javascript dans la version souhaitée
🡺  Support des nouvelles syntaxes Ecmascript sur tous navigateurs

interface IAnimal {
  name: string
  legs: number
}

interface ICat extends IAnimal {
  legs: 4,
  color: string
}

const garfield: ICat = {
  name: 'Garfield',
  legs: 4,
  color: 'orange'
}

function getName(animal: IAnimal): string {
  return animal.name
}

function getColor(cat: ICat): string {
  return cat.color
}

console.log('Hey', getName(garfield))
console.log('Cat color:', getColor(garfield))

Exemple de typage :

Boilerplate de Microsoft, avec Redux :

Boilerplates React + Typescript

create-react-app pour Typescript

https://github.com/Microsoft/TypeScript-React-Starter

https://github.com/wmonk/create-react-app-typescript

Parcel pour un petit projet

Bundlers

Webpack sinon

Support de Typescript par défaut

Pas plus de config que pour du JS standard.

Avant :

  • babel-loader
  • babel-preset-react-app
  • babel-plugin-transform-
    runtime
  • babel-preset-es2015
  • babel-preset-stage-0
  • eslint
  • eslint-plugin-jsx-a11y
  • eslint-plugin-react
  • typescript
  • ts-loader
  • tslint

Après :

Packages pour Babel + Linter

Ou, mieux que ts-loader :
awesome-typescript-loader

React a des typings à jour

Packages de typings

à installer dans les devDependencies :

yarn add -D @types/react @types/react-dom

package.json

Packages avec Parcel

{
  "name": "react-typescript",
  "license": "MIT",
  "scripts": {
    "start": "parcel src/index.html -d public",
    "build": "parcel build src/index.html --public-url ./"
  },
  "dependencies": {
    "react": "^16.4.1",
    "react-dom": "^16.4.1"
  },
  "devDependencies": {
    "@types/react": "^16.4.1",
    "@types/react-dom": "^16.0.6",
    "parcel-bundler": "^1.9.2",
    "tslint": "^5.10.0",
    "typescript": "^2.9.2"
  }
}

tsconfig.json

Config de Typescript

{
  "compilerOptions": {
    "jsx": "react",
    "target": "es2015",
    "module": "es2015",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "pretty": true,
    "strictNullChecks": true
  }
}

Qu'est-ce qu'on va typer ?

  • Les props et state des composants
  • Les actions et reducers Redux
  • Les events du DOM
  • Les HOC
  • Les DTO
  • Potentiellement toutes les valeurs
    et fonctions, et même le style !

À première vue,

aucune différence :

import React from 'react'

const App = () => (
  <h1>Hello World!</h1>
)

export default App

On commence par nommer

les fichiers en .tsx

Une interface de props

pour chaque composant :

import React from "react"

interface IProps {
  firstname: string
  age: number
}

const Person = ({ firstname, age }: IProps) => (
  <div>
    <h2>My name is {firstname}</h2>
    <p>I'm {age}.</p>
  </div>
)

export default Person

On peut typer explicitement

un composant stateless :

const App: React.SFC = () => (
  <h1>Hello World!</h1>
)

// Pareil mais plus verbeux
const App: React.StatelessComponent = () => (
  <h1>Hello World!</h1>
)

// Avec des props
const Person: React.SFC<IProps> = ({ firstname, age }) => (
  <div>
    <h2>My name is {firstname}</h2>
    <p>I'm {age}.</p>
  </div>
)

VSCode est votre ami

Il utilise automatiquement

les typings installés pour vous aider

Imports automatiques

Auto-complétion des props

Validation des props

Exemple d'inférence

du type CSSProperties :

Composant stateful (classique) :

Inférence de bout en bout :

(aucune différence ici avec du JS)

Types pour les

event handlers de formulaire

Render Props

Avec Typescript on se sent assisté

et le refactoring devient un vrai plaisir

https://github.com/sw-yx/react-typescript-cheatsheet

React Typescript Cheatsheet

Adoption et croissance

React

vs

Typescript

NPM

03/2015 - 06/2018

Google Trends

https://slides.com/godefroy_dc/react-typescript-2018-06

Slides

https://github.com/Godefroy/react-typescript-demo

Projet démo

Merci !

Co-fondateur de

Godefroy de Compreignac

Twitter : @Godefroy

React + Typescript = <3

By godefroy_dc

React + Typescript = <3

Pourquoi et comment utiliser React avec Typescript. Talk "React Nantes" du 28/06/2018.

  • 202