Skip to content

Commit

Permalink
Updated React CheatSheet
Browse files Browse the repository at this point in the history
- Added new react type example HTMLProps
- Added note about ComponentProps shortcomings
Related #170
  • Loading branch information
piotrwitek committed May 17, 2019
1 parent f402ba6 commit 0e28cd2
Show file tree
Hide file tree
Showing 2 changed files with 252 additions and 28 deletions.
140 changes: 126 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [React & Redux in TypeScript - Static Typing Guide](#react--redux-in-typescript---static-typing-guide)
- [Contributing Guide](#contributing-guide)
- [Funding](#funding)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Type-Definitions for React & Redux](#type-definitions-for-react--redux)
- [React - Type-Definitions Cheatsheet](#react---type-definitions-cheatsheet)
- [`React.FunctionComponent<P>` or `React.FC<P>`](#reactfunctioncomponentp-or-reactfcp)
- [`React.Component<P, S>`](#reactcomponentp-s)
- [`React.ComponentProps<typeof Component>`](#reactcomponentpropstypeof-component)
- [`React.ComponentType<P>`](#reactcomponenttypep)
- [`React.ReactElement` or `JSX.Element`](#reactreactelement-or-jsxelement)
- [`React.ReactNode`](#reactreactnode)
- [`React.CSSProperties`](#reactcssproperties)
- [`React.HTMLProps<HTMLXXXElement>`](#reacthtmlpropshtmlxxxelement)
- [`React.ReactEventHandler<HTMLXXXElement>`](#reactreacteventhandlerhtmlxxxelement)
- [`React.MouseEvent<HTMLXXXElement>` | `React.KeyboardEvent<HTMLXXXElement>` | `React.TouchEvent<HTMLXXXElement>` etc...](#reactmouseeventhtmlxxxelement--reactkeyboardeventhtmlxxxelement--reacttoucheventhtmlxxxelement-etc)
- [React - Typing Patterns](#react---typing-patterns)
- [Function Components - FC](#function-components---fc)
- [- FC counter](#--fc-counter)
- [- spread attributes link](#--spread-attributes-link)
- [Class Components](#class-components)
- [- class counter](#--class-counter)
- [- with default props](#--with-default-props)
- [Generic Components](#generic-components)
- [- generic list](#--generic-list)
- [Render Props](#render-props)
- [- name provider](#--name-provider)
- [- mouse provider](#--mouse-provider)
- [Higher-Order Components](#higher-order-components)
- [- withState](#--withstate)
- [- withErrorBoundary](#--witherrorboundary)
- [Redux Connected Components](#redux-connected-components)
- [- redux connected counter](#--redux-connected-counter)
- [- redux connected counter with own props](#--redux-connected-counter-with-own-props)
- [- redux connected counter with `redux-thunk` integration](#--redux-connected-counter-with-redux-thunk-integration)
- [Context](#context)
- [ThemeContext](#themecontext)
- [ThemeProvider](#themeprovider)
- [ThemeConsumer](#themeconsumer)
- [ThemeConsumer in class component](#themeconsumer-in-class-component)
- [Hooks](#hooks)
- [- useState](#--usestate)
- [- useReducer](#--usereducer)
- [- useContext](#--usecontext)
- [Redux - Typing Patterns](#redux---typing-patterns)
- [Store Configuration](#store-configuration)
- [Create Global RootState and RootAction Types](#create-global-rootstate-and-rootaction-types)
- [`RootState` - type representing root state-tree](#rootstate---type-representing-root-state-tree)
- [`RootAction` - type representing union type of all action objects](#rootaction---type-representing-union-type-of-all-action-objects)
- [Create Store](#create-store)
- [Action Creators](#action-creators)
- [Reducers](#reducers)
- [State with Type-level Immutability](#state-with-type-level-immutability)
- [Caveat - `Readonly` is not recursive](#caveat---readonly-is-not-recursive)
- [Solution - recursive `Readonly` is called `DeepReadonly`](#solution---recursive-readonly-is-called-deepreadonly)
- [Typing reducer](#typing-reducer)
- [Typing reducer with `typesafe-actions`](#typing-reducer-with-typesafe-actions)
- [Testing reducer](#testing-reducer)
- [Async Flow with `redux-observable`](#async-flow-with-redux-observable)
- [Typing epics](#typing-epics)
- [Testing epics](#testing-epics)
- [Selectors with `reselect`](#selectors-with-reselect)
- [Connect with `react-redux`](#connect-with-react-redux)
- [Typing connected component](#typing-connected-component)
- [Typing connected component using `redux-thunk` action creators](#typing-connected-component-using-redux-thunk-action-creators)
- [Configuration & Dev Tools](#configuration--dev-tools)
- [Common Npm Scripts](#common-npm-scripts)
- [TypeScript](#typescript)
- [tsconfig.json](#tsconfigjson)
- [TSLib](#tslib)
- [TSLint](#tslint)
- [tslint.json](#tslintjson)
- [ESLint](#eslint)
- [.eslintrc](#eslintrc)
- [Jest](#jest)
- [jest.config.json](#jestconfigjson)
- [jest.stubs.js](#jeststubsjs)
- [Style Guide](#style-guide)
- ["react-styleguidist"](#react-styleguidist)
- [Recipes](#recipes)
- [General Tips](#general-tips)
- [- should I still use React.PropTypes in TS?](#--should-i-still-use-reactproptypes-in-ts)
- [- when to use `interface` declarations and when `type` aliases?](#--when-to-use-interface-declarations-and-when-type-aliases)
- [- what's better default or named exports?](#--whats-better-default-or-named-exports)
- [- how to best initialize class instance or static properties?](#--how-to-best-initialize-class-instance-or-static-properties)
- [- how to best declare component handler functions?](#--how-to-best-declare-component-handler-functions)
- [Ambient Modules Tips](#ambient-modules-tips)
- [Imports in ambient modules](#imports-in-ambient-modules)
- [Type-Definitions Tips](#type-definitions-tips)
- [Missing type-definitions error](#missing-type-definitions-error)
- [Using custom `d.ts` files for npm modules](#using-custom-dts-files-for-npm-modules)
- [Type Augmentation Tips](#type-augmentation-tips)
- [Augmenting library internal declarations - using relative import](#augmenting-library-internal-declarations---using-relative-import)
- [Augmenting library public declarations - using node_modules import](#augmenting-library-public-declarations---using-node_modules-import)
- [Tutorials & Articles](#tutorials--articles)
- [Contributors](#contributors)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

<div align="center">

## React & Redux in TypeScript - Static Typing Guide
Expand Down Expand Up @@ -123,32 +227,32 @@ npm i -D @types/react @types/react-dom @types/react-redux

# React - Type-Definitions Cheatsheet

#### `React.FunctionComponent<P>` or `React.FC<P>`
#### `React.FC<Props>` or `React.FunctionComponent<Props>`
Type representing a functional component
```tsx
const MyComponent: React.FC<Props> = ...
```

#### `React.Component<P, S>`
#### `React.Component<Props, State>`
Type representing a class component
```tsx
class MyComponent extends React.Component<Props, State> { ...
```
#### `React.ComponentProps<typeof Component>`
Gets type of Component Props, so you don't need to export Props from your component ever! (Works for both FC and Class components)
```tsx
type MyComponentProps = React.ComponentProps<typeof MyComponent>;
```
#### `React.ComponentType<P>`
Type representing union type of (React.FC | React.Component)
#### `React.ComponentType<Props>`
Type representing union of (React.FC<Props> | React.Component<Props>) - used in HOC
```tsx
const withState = <P extends WrappedComponentProps>(
WrappedComponent: React.ComponentType<P>,
) => { ...
```
#### `React.ComponentProps<typeof XXX>`
Gets Props type of a specified component XXX (WARNING: does not work with statically declared default props and generic props)
```tsx
type MyComponentProps = React.ComponentProps<typeof MyComponent>;
```
#### `React.ReactElement` or `JSX.Element`
Type representing a concept of React Element - representation of a native DOM component (e.g. `<div />`), or a user-defined composite component (e.g. `<MyComponent />`)
```tsx
Expand All @@ -163,21 +267,29 @@ const Component = ({ children: React.ReactNode }) => ...
```
#### `React.CSSProperties`
Type representing style object in JSX (useful for css-in-js styles)
Type representing style object in JSX - for css-in-js styles
```tsx
const styles: React.CSSProperties = { flexDirection: 'row', ...
const element = <div style={styles} ...
```

#### `React.ReactEventHandler<E>`
Type representing generic event handler
#### `React.HTMLProps<HTMLXXXElement>`
Type representing Props of specified HTML Element - for extending HTML Elements
```tsx
const Input: React.FC<Props & React.HTMLProps<HTMLInputElement>> = props => { ... }

<Input about={...} accept={...} alt={...} ... />
```
#### `React.ReactEventHandler<HTMLXXXElement>`
Type representing generic event handler - for declaring event handlers
```tsx
const handleChange: React.ReactEventHandler<HTMLInputElement> = (ev) => { ... }

<input onChange={handleChange} ... />
```
#### `React.MouseEvent<E>` | `React.KeyboardEvent<E>` | `React.TouchEvent<E>` etc...
#### `React.MouseEvent<HTMLXXXElement>` | `React.KeyboardEvent<HTMLXXXElement>` | `React.TouchEvent<HTMLXXXElement>` etc...
Type representing more specific event handler
```tsx
const handleChange = (ev: React.MouseEvent<HTMLDivElement>) => { ... }
Expand Down
140 changes: 126 additions & 14 deletions README_SOURCE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [React & Redux in TypeScript - Static Typing Guide](#react--redux-in-typescript---static-typing-guide)
- [Contributing Guide](#contributing-guide)
- [Funding](#funding)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Type-Definitions for React & Redux](#type-definitions-for-react--redux)
- [React - Type-Definitions Cheatsheet](#react---type-definitions-cheatsheet)
- [`React.FunctionComponent<P>` or `React.FC<P>`](#reactfunctioncomponentp-or-reactfcp)
- [`React.Component<P, S>`](#reactcomponentp-s)
- [`React.ComponentProps<typeof Component>`](#reactcomponentpropstypeof-component)
- [`React.ComponentType<P>`](#reactcomponenttypep)
- [`React.ReactElement` or `JSX.Element`](#reactreactelement-or-jsxelement)
- [`React.ReactNode`](#reactreactnode)
- [`React.CSSProperties`](#reactcssproperties)
- [`React.HTMLProps<HTMLXXXElement>`](#reacthtmlpropshtmlxxxelement)
- [`React.ReactEventHandler<HTMLXXXElement>`](#reactreacteventhandlerhtmlxxxelement)
- [`React.MouseEvent<HTMLXXXElement>` | `React.KeyboardEvent<HTMLXXXElement>` | `React.TouchEvent<HTMLXXXElement>` etc...](#reactmouseeventhtmlxxxelement--reactkeyboardeventhtmlxxxelement--reacttoucheventhtmlxxxelement-etc)
- [React - Typing Patterns](#react---typing-patterns)
- [Function Components - FC](#function-components---fc)
- [- FC counter](#--fc-counter)
- [- spread attributes link](#--spread-attributes-link)
- [Class Components](#class-components)
- [- class counter](#--class-counter)
- [- with default props](#--with-default-props)
- [Generic Components](#generic-components)
- [- generic list](#--generic-list)
- [Render Props](#render-props)
- [- name provider](#--name-provider)
- [- mouse provider](#--mouse-provider)
- [Higher-Order Components](#higher-order-components)
- [- withState](#--withstate)
- [- withErrorBoundary](#--witherrorboundary)
- [Redux Connected Components](#redux-connected-components)
- [- redux connected counter](#--redux-connected-counter)
- [- redux connected counter with own props](#--redux-connected-counter-with-own-props)
- [- redux connected counter with `redux-thunk` integration](#--redux-connected-counter-with-redux-thunk-integration)
- [Context](#context)
- [ThemeContext](#themecontext)
- [ThemeProvider](#themeprovider)
- [ThemeConsumer](#themeconsumer)
- [ThemeConsumer in class component](#themeconsumer-in-class-component)
- [Hooks](#hooks)
- [- useState](#--usestate)
- [- useReducer](#--usereducer)
- [- useContext](#--usecontext)
- [Redux - Typing Patterns](#redux---typing-patterns)
- [Store Configuration](#store-configuration)
- [Create Global RootState and RootAction Types](#create-global-rootstate-and-rootaction-types)
- [`RootState` - type representing root state-tree](#rootstate---type-representing-root-state-tree)
- [`RootAction` - type representing union type of all action objects](#rootaction---type-representing-union-type-of-all-action-objects)
- [Create Store](#create-store)
- [Action Creators](#action-creators)
- [Reducers](#reducers)
- [State with Type-level Immutability](#state-with-type-level-immutability)
- [Caveat - `Readonly` is not recursive](#caveat---readonly-is-not-recursive)
- [Solution - recursive `Readonly` is called `DeepReadonly`](#solution---recursive-readonly-is-called-deepreadonly)
- [Typing reducer](#typing-reducer)
- [Typing reducer with `typesafe-actions`](#typing-reducer-with-typesafe-actions)
- [Testing reducer](#testing-reducer)
- [Async Flow with `redux-observable`](#async-flow-with-redux-observable)
- [Typing epics](#typing-epics)
- [Testing epics](#testing-epics)
- [Selectors with `reselect`](#selectors-with-reselect)
- [Connect with `react-redux`](#connect-with-react-redux)
- [Typing connected component](#typing-connected-component)
- [Typing connected component using `redux-thunk` action creators](#typing-connected-component-using-redux-thunk-action-creators)
- [Configuration & Dev Tools](#configuration--dev-tools)
- [Common Npm Scripts](#common-npm-scripts)
- [TypeScript](#typescript)
- [tsconfig.json](#tsconfigjson)
- [TSLib](#tslib)
- [TSLint](#tslint)
- [tslint.json](#tslintjson)
- [ESLint](#eslint)
- [.eslintrc](#eslintrc)
- [Jest](#jest)
- [jest.config.json](#jestconfigjson)
- [jest.stubs.js](#jeststubsjs)
- [Style Guide](#style-guide)
- ["react-styleguidist"](#react-styleguidist)
- [Recipes](#recipes)
- [General Tips](#general-tips)
- [- should I still use React.PropTypes in TS?](#--should-i-still-use-reactproptypes-in-ts)
- [- when to use `interface` declarations and when `type` aliases?](#--when-to-use-interface-declarations-and-when-type-aliases)
- [- what's better default or named exports?](#--whats-better-default-or-named-exports)
- [- how to best initialize class instance or static properties?](#--how-to-best-initialize-class-instance-or-static-properties)
- [- how to best declare component handler functions?](#--how-to-best-declare-component-handler-functions)
- [Ambient Modules Tips](#ambient-modules-tips)
- [Imports in ambient modules](#imports-in-ambient-modules)
- [Type-Definitions Tips](#type-definitions-tips)
- [Missing type-definitions error](#missing-type-definitions-error)
- [Using custom `d.ts` files for npm modules](#using-custom-dts-files-for-npm-modules)
- [Type Augmentation Tips](#type-augmentation-tips)
- [Augmenting library internal declarations - using relative import](#augmenting-library-internal-declarations---using-relative-import)
- [Augmenting library public declarations - using node_modules import](#augmenting-library-public-declarations---using-node_modules-import)
- [Tutorials & Articles](#tutorials--articles)
- [Contributors](#contributors)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

<div align="center">

## React & Redux in TypeScript - Static Typing Guide
Expand Down Expand Up @@ -123,32 +227,32 @@ npm i -D @types/react @types/react-dom @types/react-redux

# React - Type-Definitions Cheatsheet

#### `React.FunctionComponent<P>` or `React.FC<P>`
#### `React.FC<Props>` or `React.FunctionComponent<Props>`
Type representing a functional component
```tsx
const MyComponent: React.FC<Props> = ...
```

#### `React.Component<P, S>`
#### `React.Component<Props, State>`
Type representing a class component
```tsx
class MyComponent extends React.Component<Props, State> { ...
```
#### `React.ComponentProps<typeof Component>`
Gets type of Component Props, so you don't need to export Props from your component ever! (Works for both FC and Class components)
```tsx
type MyComponentProps = React.ComponentProps<typeof MyComponent>;
```
#### `React.ComponentType<P>`
Type representing union type of (React.FC | React.Component)
#### `React.ComponentType<Props>`
Type representing union of (React.FC<Props> | React.Component<Props>) - used in HOC
```tsx
const withState = <P extends WrappedComponentProps>(
WrappedComponent: React.ComponentType<P>,
) => { ...
```
#### `React.ComponentProps<typeof XXX>`
Gets Props type of a specified component XXX (WARNING: does not work with statically declared default props and generic props)
```tsx
type MyComponentProps = React.ComponentProps<typeof MyComponent>;
```
#### `React.ReactElement` or `JSX.Element`
Type representing a concept of React Element - representation of a native DOM component (e.g. `<div />`), or a user-defined composite component (e.g. `<MyComponent />`)
```tsx
Expand All @@ -163,21 +267,29 @@ const Component = ({ children: React.ReactNode }) => ...
```
#### `React.CSSProperties`
Type representing style object in JSX (useful for css-in-js styles)
Type representing style object in JSX - for css-in-js styles
```tsx
const styles: React.CSSProperties = { flexDirection: 'row', ...
const element = <div style={styles} ...
```

#### `React.ReactEventHandler<E>`
Type representing generic event handler
#### `React.HTMLProps<HTMLXXXElement>`
Type representing Props of specified HTML Element - for extending HTML Elements
```tsx
const Input: React.FC<Props & React.HTMLProps<HTMLInputElement>> = props => { ... }

<Input about={...} accept={...} alt={...} ... />
```
#### `React.ReactEventHandler<HTMLXXXElement>`
Type representing generic event handler - for declaring event handlers
```tsx
const handleChange: React.ReactEventHandler<HTMLInputElement> = (ev) => { ... }

<input onChange={handleChange} ... />
```
#### `React.MouseEvent<E>` | `React.KeyboardEvent<E>` | `React.TouchEvent<E>` etc...
#### `React.MouseEvent<HTMLXXXElement>` | `React.KeyboardEvent<HTMLXXXElement>` | `React.TouchEvent<HTMLXXXElement>` etc...
Type representing more specific event handler
```tsx
const handleChange = (ev: React.MouseEvent<HTMLDivElement>) => { ... }
Expand Down

0 comments on commit 0e28cd2

Please sign in to comment.