PropTypes and Flow as Legacy

You will meet both in older code; neither is a choice for new work.

PropTypes 4,446 checked props at runtime, in development builds only, warning in the console when a value had the wrong type or a required prop was missing. Declarations hung off the component as a static property — Greeting.propTypes = { name: PropTypes.string, children: PropTypes.element.isRequired }. React 19 7,897 dropped support: propTypes on a function component is ignored, so such code runs but checks nothing. The prop-types package remains on npm 2,036 at 15.8.1, last published in 2023, for older React versions.

Reading PropTypes declarations as TypeScript types
PropTypes TypeScript
PropTypes.string name?: string
PropTypes.string.isRequired name: string
PropTypes.oneOf(['a', 'b']) kind: 'a' | 'b'
PropTypes.node / .element ReactNode / ReactElement
PropTypes.shape({...}) an interface

The two differ in kind. PropTypes validated values that arrived, one render at a time, in the browser; TypeScript validates call sites, all of them, before the code ships — which is why a component nobody rendered during testing went unchecked.

Flow is Meta's own static checker, built alongside React and still released regularly — version 0.331 appeared in September 2026 — but its use outside Meta has collapsed. Its syntax is close enough to TypeScript's (type Props = { name: string }) that converting a file is usually mechanical. Its distinguishing feature is aggressive inference: a file marked // @flow is checked even with no annotations, so square("2") against function square(n) { return n * n; } is an error. flow-remove-types strips the annotations when you migrate away.