Static Type Checking - could use some experienced guiding


(Ben Carp) #1

There are many ways to use static type checking - TypeScript, Flow, and in React proptypes. Any thoughts or recommendation as to which to use for React projects?
Also, this is Flow’s instructions for using flow with Create-React-App https://flow.org/en/docs/tools/create-react-app/ . They instruct you on how to use it with Yarn, but I use NPM. Any suggestions?
Thanks in advance!


(Eric Masiello) #2

I have some experience with all 3, some more than others. Here’s my quick summary of the pros/cons of each:

React PropTypes:

  • + Easiest to set up
  • + Does development-only run time analysis of your components to verify the correct data is being passed to components
  • + Requires no additional configuration beyond what you already would use for compiling/bundling React
  • - Only useful for React components (no way to type check anything that isn’t React)
  • - Does not provide static analysis of your components at author time. In other words, you won’t be able to use tools like VSCode to tell you at author-time whether or not the way you’re writing your code is valid. The only way you’ll know is by running it in the browser and then letting the PropTypes library output errors to your browser console

Flow

  • + Provides static analysis of all your JavaScript - not just React components
  • + Relatively easy to setup if you’re already using Babel
  • + Decent to good IDE integration (for things like VSCode, Atom, etc.)
  • + Good documentation
  • + Very easy to mix Flow type checked and non-Flow type checked code
  • - 3rd party library support is less than stellar once you step outside the React ecosystem which means there’s good chance you’ll end of writing a lot of type definitions for libraries you didn’t author
  • - I find the errors produced by Flow difficult to decipher
  • - You need to set up a separate “type checking” process independent of your normal Babel-compile process (however, you can configure Webpack to do both on every file change but it requires additional Webpack configuration)

Typescript

  • + Provides static analysis of all your Typescript files (*.ts) and Typescript React/JSX files (*.tsx)
  • + Good documentation
  • + If you use VSCode as your editor, Typescript editor support is built in and its fantastic!
  • +/- This one is kinda a pro and a con depending on your stand point: You’ll need to use the Typescript compiler - not Babel. Typescripts compiler is really good and on the plus side, it does both compilation (converting typescript to ES5/6 code) and type checking so you won’t need two separate processes
  • + At least when compared to Flow, 3rd party library type definitions are much easier to come by. That isn’t to say you won’t ever find yourself writing type defs for someone else but its much much easier not to
  • +/- Another plus and minus here: I find typescripts error messages on non-React code very easy to understand. On the React side of things, I always end skimming over most of the error and just paying attention to the last sentence or two.
  • +/- Another plus and minus here: While you can mix regular JS code with Typescript code, its not as easy as it is with Flow. That said, its not particularly difficult either. So with Flow or Typescript, if you have an existing code base that you want to progressively add type checking to, its possible with either.

So here’s my hot take:
If this is a small project and something you wanna get out the door quickly, stick with PropTypes. Its the easiest to integrate and when you see an error, its pretty obvious what went wrong. Flow and Typescript are more suitable to larger projects or anytime you’re dealing with complex and/or deeply nested data structures. Having used both Flow and Typescript, I like how Flow integrates so seamlessly with an existing Babel compiled project. That said, the 3rd party library support is a huge let down. I’ve since started using Typescript and have been much happier on that front. So at the moment, my choices are Typescript or Proptypes. Keep in mind, if you’re used the freedom of plain JavaScript and you decide to adopt Flow or Typescript, be ready for a learning curve. You’re gonna encounter a number of type checking errors that don’t make a lot of sense at first. That said, learn the escape hatches that each language provides. When all else fails, define something as an any type or use the // ignore comment flags that are provided by the type systems. Do this as a last resort though. The ignore and any types effectively remove any value that Flow and Typescript add. Personally, I only do this when I need to get something out the door and I always make it a point to come back later and fix it when I have time.


(Ben Carp) #3

This is valuable. Thanks!

Not sure what you mean here. Do you mean “Typescript and Proptypes”, since Proptypes is executed by Babel?


(Eric Masiello) #4

Sorry, where I said “Babel” I meant “PropTypes”. I corrected my summary above.


(Jason Sooter) #5

I have been using Flow for about a year now. I agree with the thorough summary above. I don’t have any TS experience unfortunately.

A thought I have had for the last couple months is why PropTypes even exist now. I am not sure if this applies to Typescript but it is quite easy to get the benefit of PropTypes with Flow if dealing with just React. I’m hoping someone can contradict me on this but I’d break these 3 options into 2 categories. Those that want Strongly Typed code (Flow & TS) and those that want some validation that their React Code is correct.

The complexity of Flow (and I expect TS) goes up when dealing with other non-react code and libraries that you end up using. And PropTypes has no relevant value in this area.


(Eric Masiello) #6

I still think proptypes has its place. It’s by far the easiest type tool to bolt on to an existing project and doesn’t require the cognitive lift that Flow or TS do with their rather gnarly React errors.

That all said, I’m pretty much all in on TS at this point.


(Jason Sooter) #7

Yeah. I agree that PropTypes likely still has a place. I think my questioning revolves around if the Venn Diagram of PropTypes & Flow/TS overlaps at all. It seems like anyone that would land on PropTypes as their decision shouldn’t even consider Flow/TS and anyone who wants the benefits of Strong Typing shouldn’t consider PropTypes


(Eric Masiello) #8

You are correct in that technically PropTypes and TS/Flow are different in that one is responding at run time (PropTypes) and the other is at author time (TS/Flow). So you could use both.

As someone adopting static type checking, you’re gonna quickly feel like you’re duplicating efforts by defining static types for your system of choice and then doing it again in PropType land.

e.g.

// MyComp.tsx

interface Props {
  title: string;
  className?: string;
}

const MyComp: React.SFC<Props> = (props) => (
  <div className={props.className}>{props.title}</div>
);

// ughhhh... now im defining the same types in a different way.
MyComp.propTypes = {
  title: PropTypes.string.isRequired,
  className: PropTypes.string,
};

I believe that 98% of the time, your static types will catch anything a PropTypes would at run time anyway. So to answer your question, I don’t think there really is a Venn diagram for static type checking and PropTypes. It would be way too “belt and suspenders”.


(Jason Sooter) #9

Nice Analogy. I completely agree