Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React and Type Systems

React and Type Systems

In the present talk, I discuss the use of various type systems in the context of Front End web development in general, and React-based systems in particular. While I am giving a brief overview of the debate within the JavaScript community concerning the perceived merits and drawbacks of introducing types to the language, the main focus of the presentation will be an aspect I've dubbed "ecological", whose main concern is viability and stability of rich distributed ecosystems of reusable components.

Jiri Tobisek

February 23, 2016
Tweet

More Decks by Jiri Tobisek

Other Decks in Programming

Transcript

  1. var a = { a: 1, b: 2, c: 3

    } _.map(a, x => 2 * x);
  2. var a = { a: 1, b: 2, c: 3

    }; _.map(a, x => 2 * x); // [2, 4, 6]
  3. var a = "Weakly typed..."; _.map(a, x => 2 *

    x); // [NaN, NaN, NaN, NaN, NaN, NaN, 0, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
  4. Contract An agreement between the supplier and the client of

    a piece of code (component, API call, class, function).
  5. var DancingMonkey = React.createClass({ getInitialState() { return { tempo: this.props.initialTempo;

    }; } render() { return ( <svg:animated-monkey> <svg:paw speed={this.state.tempo}/> </svg:animated-monkey> ); } });
  6. DancingMonkey.jsx: The Contract Natural Language “To enjoy the core feature

    of our DancingMonkey component, render it, while specifying its initial tempo as number of bps…” ReactDOM.render(<DancingMonkey initialTempo={200} />, container);
  7. var DancingMonkey = React.createClass({ tempos: { "allegretto": 120, "prestissimo": 200

    } getInitialState() { var initialTempo = this.props.initialTempo; return { tempo: this.tempos[initialTempo] }; } ... });
  8. var DancingMonkey = React.createClass({ … getInitialState() { var initialTempo =

    this.props.initialTempo; if(!typeof initialTempo === "string") { throw new Error("Must be a string!"); } return { tempo: this.tempos[initialTempo] }; } … });
  9. function mergeIntoWithNoDuplicateKeys(one, two) { invariant( one && two && typeof

    one === 'object' && typeof two === ‘object', 'mergeIntoWithNoDuplicateKeys(): Cannot merge…’ ); for (var key in two) { ...
  10. DancingMonkey.jsx: The Contract React’s PropTypes var DancingMonkey = React.createClass({ propTypes:

    { "initialTempo": React.PropTypes.oneOf([ "allegretto", ”prestissimo” ]) }
  11. TypeScript Complete language and toolset ‣ transpiler ‣ type checker

    ‣ code intelligence (“Language Services”) https://github.com/Microsoft/TypeScript
  12. function tempoNameToBpm(name: string): number { var tempo: number = tempos[name];

    if(tempo === undefined) { return 120; } else { return tempo; } }
  13. function tempoNameToBpm(name: string): number { var tempo: number = tempos[name];

    if(tempo === undefined) { return 120; } else { return tempo; } }
  14. Rich type system: ‣ classes & interfaces ‣ enums ‣

    union & intersection types ‣ generics TypeScript
  15. function createFactory<P>( type: string ): DOMFactory<P>; function createFactory<P>( type: ClassicComponentClass<P>

    ): ClassicFactory<P>; function createElement<P>( type: string, props?: P, ...children: ReactNode[] ): DOMElement<P>;
  16. function render() { return <DancingMonkey initialTempo={120} /> } Type 'number'

    is not assignable to type '"allegretto" | "prestissimo"'.
  17. // @flow interface Props { initialTempo: 'allegretto' | 'prestissimo' }

    interface State { tempo: number; } class DancingMonkey extends React.Component<Props, Props, State> { static defaultProps: Props = { initialTempo: 'allegretto' }; state: State; ... }
  18. // @flow interface Props { initialTempo: 'allegretto' | 'prestissimo' }

    interface State { tempo: number; } class DancingMonkey extends React.Component<Props, Props, State> { static defaultProps: Props = { initialTempo: 'allegretto' }; state: State; ... }
  19. type Tempo = 'allegretto' | 'prestissimo'; interface Props { initialTempo?:

    Tempo } class DancingMonkey extends React.Component<Props, State> { getInitialState(): State { var initialTempo = this.props.initialTempo; return { tempo: this.tempos[initialTempo] }; } });
  20. type Tempo = 'allegretto' | 'prestissimo'; interface Props { initialTempo?:

    Tempo } class DancingMonkey extends React.Component<Props, State> { getInitialState(): State { var initialTempo = this.props.initialTempo; return { tempo: this.tempos[initialTempo] }; } });
  21. So, Should I Employ A Type System? Are you are

    creating a living part of a larger ecosystem?