) 集合的类型 - 用于 HOC
+```tsx
+const withState = (
+ WrappedComponent: React.ComponentType
,
+) => { ...
+```
+
+### `React.ComponentProps`
+取得组件 XXX 的 Props 类型(警告:无法用于静态声明的 default props 以及泛型 props)
+```tsx
+type MyComponentProps = React.ComponentProps;
+```
+
+### `React.ReactElement` | `JSX.Element`
+表示 React 中 Element 概念的类型 - 表示一个原生 DOM 组件(比如 ``)或用户自定义的复合组件 (比如 ``)
+```tsx
+const elementOnly: React.ReactElement = || ;
+```
+
+### `React.ReactNode`
+表示任意类型的 React 节点(相当于 ReactElement (包括 Fragments 和 Portals) + 原始 JS 类型)
+```tsx
+const elementOrPrimitive: React.ReactNode = 'string' || 0 || false || null || undefined || || ;
+const Component = ({ children: React.ReactNode }) => ...
+```
+
+### `React.CSSProperties`
+表示 JSX 中样式对象的类型 - 实现 css-in-js 风格
+```tsx
+const styles: React.CSSProperties = { flexDirection: 'row', ...
+const element = `
+表示指定 HTML 元素的类型 - 用于扩展 HTML 元素
+```tsx
+const Input: React.FC
> = props => { ... }
+
+
+```
+
+### `React.ReactEventHandler`
+表示 event handler 的泛型类型 - 用于声明 event handlers
+```tsx
+const handleChange: React.ReactEventHandler = (ev) => { ... }
+
+
+```
+
+### `React.XXXEvent`
+表示更多特殊 event。一些常见的 event 例如:`ChangeEvent, FormEvent, FocusEvent, KeyboardEvent, MouseEvent, DragEvent, PointerEvent, WheelEvent, TouchEvent`。
+```tsx
+const handleChange = (ev: React.MouseEvent) => { ... }
+
+
+```
+
+上一段代码中的 `React.MouseEvent` 表示鼠标事件的类型,这个事件挂载在 `HTMLDivElement` 上。
+
+[⇧ 返回顶部](#目录)
+
+---
+
+# React - 类型模式
+
+## Function Components - FC
+
+### - 计数器组件
+
+::codeblock='playground/src/components/fc-counter.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#fccounter)
+
+[⇧ 返回顶部](#目录)
+
+### - 组件的 [属性展开](https://zh-hans.reactjs.org/docs/jsx-in-depth.html#spread-attributes)
+
+::codeblock='playground/src/components/fc-spread-attributes.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#fcspreadattributes)
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## Class Components
+
+### - 计数器组件 Class 版
+
+::codeblock='playground/src/components/class-counter.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#classcounter)
+
+[⇧ 返回顶部](#目录)
+
+### - Class 组件和 default props
+
+::codeblock='playground/src/components/class-counter-with-default-props.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#classcounterwithdefaultprops)
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## 泛型组件
+- 易于生成不同类型的变种组件,同时复用公共逻辑
+- 常见的用例是泛型列表组件
+
+### - 泛型列表组件
+
+::codeblock='playground/src/components/generic-list.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#genericlist)
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## Render Props
+> https://zh-hans.reactjs.org/docs/render-props.html
+
+### - Name Provider 组件
+> 将 children 用作 render prop 的简单组件
+
+::codeblock='playground/src/components/name-provider.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#nameprovider)
+
+[⇧ 返回顶部](#目录)
+
+### - Mouse Provider 组件
+> `Mouse` 组件的例子来源于 [Render Props - React 文档](https://zh-hans.reactjs.org/docs/render-props.html#use-render-props-for-cross-cutting-concerns)
+
+::codeblock='playground/src/components/mouse-provider.tsx'::
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/#mouseprovider)
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## 高阶组件
+> https://zh-hans.reactjs.org/docs/higher-order-components.html
+
+### - 用 HOC 封装一个组件
+给无状态的计数器加上状态
+
+::codeblock='playground/src/hoc/with-state.tsx'::
+::expander='playground/src/hoc/with-state.usage.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### - 用 HOC 封装组件并注入 props
+用 componentDidCatch 给任意组件加上错误处理功能
+
+::codeblock='playground/src/hoc/with-error-boundary.tsx'::
+::expander='playground/src/hoc/with-error-boundary.usage.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### - 嵌套 HOC - 封装组件,props 注入,连接到 redux 🌟
+用 componentDidCatch 给任意组件加上错误处理功能
+
+::codeblock='playground/src/hoc/with-connected-count.tsx'::
+::expander='playground/src/hoc/with-connected-count.usage.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## Redux 连接组件
+
+### - Redux 版计数器
+
+::codeblock='playground/src/connected/fc-counter-connected.tsx'::
+::expander='playground/src/connected/fc-counter-connected.usage.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### - Redux 版计数器,带自定义 props
+
+::codeblock='playground/src/connected/fc-counter-connected-own-props.tsx'::
+::expander='playground/src/connected/fc-counter-connected-own-props.usage.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### - Redux 版计数器,集成 `redux-thunk`
+
+::codeblock='playground/src/connected/fc-counter-connected-bind-action-creators.tsx'::
+::expander='playground/src/connected/fc-counter-connected-bind-action-creators.usage.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+## Context
+
+> https://zh-hans.reactjs.org/docs/context.html
+
+### ThemeContext
+
+::codeblock='playground/src/context/theme-context.ts'::
+
+[⇧ 返回顶部](#目录)
+
+### ThemeProvider
+
+::codeblock='playground/src/context/theme-provider.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### ThemeConsumer
+
+::codeblock='playground/src/context/theme-consumer.tsx'::
+
+### ThemeConsumer Class 版
+
+::codeblock='playground/src/context/theme-consumer-class.tsx'::
+
+[Implementation with Hooks](#--usecontext)
+
+[⇧ 返回顶部](#目录)
+
+## Hooks
+
+> https://zh-hans.reactjs.org/docs/hooks-intro.html
+
+### - useState
+
+> https://zh-hans.reactjs.org/docs/hooks-reference.html#usestate
+
+::codeblock='playground/src/hooks/use-state.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### - useReducer
+用于函数组件的状态管理 Hook (类似 Redux)。
+
+::codeblock='playground/src/hooks/use-reducer.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+### - useContext
+
+> https://zh-hans.reactjs.org/docs/hooks-reference.html#usecontext
+
+::codeblock='playground/src/hooks/use-theme-context.tsx'::
+
+[⇧ 返回顶部](#目录)
+
+---
+
+# Redux - 类型模式
+
+## Store 配置
+
+### 创建全局 Store 类型
+
+#### `RootState` - 表示根 state 树的类型
+可以作为 import,使用 Redux `connect` 方法连接组件时,能够确保类型安全性
+
+#### `RootAction` - 表示所有 action 对象集合的类型
+可以作为 import,用于不同层次中(reducers, sagas 或 redux-observables epics)接收和发送 redux actions
+
+::codeblock='playground/src/store/types.d.ts'::
+
+[⇧ 返回顶部](#目录)
+
+### 创建 Store
+
+当创建 store 实例时,我们不需要编写任何额外的类型,它会通过类型推断自动建立一个**类型安全的 Store 实例**。
+> 生成的 store 实例中的方法(像 `getState` 和 `dispatch`)将支持类型检查,并能够暴露所有的类型错误。
+
+::codeblock='playground/src/store/index.ts'::
+
+---
+
+## Action Creators 🌟
+
+> 我们将使用成熟的辅助库 [`typesafe-actions`](https://github.com/piotrwitek/typesafe-actions#typesafe-actions) [](https://www.npmjs.com/package/typesafe-actions) [](https://www.npmjs.com/package/typesafe-actions) 它被设计成便于使用 **TypeScript** 来写 **Redux**。
+
+> 查看这个进阶教程来学习更多:[Typesafe-Actions - Tutorial](https://github.com/piotrwitek/typesafe-actions#tutorial)!
+
+下面的方案用一个简单的工厂函数来自动创建类型安全的 action creators。目的是减少重复的 actions 和 creators 类型声明代码,并减少代码维护工作。生成结果是绝对类型安全的 action-creators 及其 actions。
+
+::codeblock='playground/src/features/counters/actions.ts'::
+::expander='playground/src/features/counters/actions.usage.ts'::
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## Reducers
+
+### 拥有 Type 层面不可变性的 State
+用 `readonly` 修饰符声明 reducer 中 `State` 的类型,可以获得编译时的不可变性
+```ts
+export type State = {
+ readonly counter: number;
+ readonly todos: ReadonlyArray;
+};
+```
+
+Readonly 修饰符允许初始化,但不允许重新赋值(编译器会提示错误)
+```ts
+export const initialState: State = {
+ counter: 0,
+}; // OK
+
+initialState.counter = 3; // TS Error: cannot be mutated
+```
+
+这对 **JS 中的 数组** 很起效,因为用 (`push`, `pop`, `splice`, ...) 这样的赋值方法将会报错,但是 (`concat`, `map`, `slice`,...) 这样的不可变方法依然是允许的。
+```ts
+state.todos.push('Learn about tagged union types') // TS Error: Property 'push' does not exist on type 'ReadonlyArray'
+const newTodos = state.todos.concat('Learn about tagged union types') // OK
+```
+
+#### 警告 - `Readonly` 不是递归的
+这意味着 `readonly` 修饰符在对象的嵌套结构中不会向下传递不变性。你需要标记每个层级的每个属性。(译注:`Readonly` 是浅比较的)
+
+> **小贴士:** 使用 `Readonly` 或 `ReadonlyArray` [映射类型](https://www.tslang.cn/docs/handbook/advanced-types.html)
+
+```ts
+export type State = Readonly<{
+ counterPairs: ReadonlyArray>,
+}>;
+
+state.counterPairs[0] = { immutableCounter1: 1, immutableCounter2: 1 }; // TS Error: cannot be mutated
+state.counterPairs[0].immutableCounter1 = 1; // TS Error: cannot be mutated
+state.counterPairs[0].immutableCounter2 = 1; // TS Error: cannot be mutated
+```
+
+#### 解决方案 - `Readonly` 的递归版本是 `DeepReadonly`
+
+为了解决上述问题,我们可以使用 [`DeepReadonly`](https://github.com/piotrwitek/utility-types#deepreadonlyt) 类型(来自 `utility-types`)。
+
+```ts
+import { DeepReadonly } from 'utility-types';
+
+export type State = DeepReadonly<{
+ containerObject: {
+ innerValue: number,
+ numbers: number[],
+ }
+}>;
+
+state.containerObject = { innerValue: 1 }; // TS Error: cannot be mutated
+state.containerObject.innerValue = 1; // TS Error: cannot be mutated
+state.containerObject.numbers.push(1); // TS Error: cannot use mutator methods
+```
+
+
+[⇧ 返回顶部](#目录)
+
+### reducer 类型声明
+
+> 为了理解下一小节,请确保了解 [类型推论](https://www.tslang.cn/docs/handbook/type-inference.html),[基于控制流的类型分析](https://www.tslang.cn/docs/release-notes/typescript-2.0.html) 以及 [标记联合类型](https://www.tslang.cn/docs/release-notes/typescript-2.0.html)
+
+::codeblock='playground/src/features/todos/reducer.ts'::
+
+[⇧ 返回顶部](#目录)
+
+### 使用 `typesafe-actions` 进行 reducer 类型声明
+> 请注意,我们不需要在 API 上使用任何泛型类型参数。可以和传统的 reducer 写法进行比较,它们是等价的。
+
+::codeblock='playground/src/features/todos/reducer-ta.ts'::
+
+[⇧ 返回顶部](#目录)
+
+### 测试 reducer
+
+::codeblock='playground/src/features/todos/reducer.spec.ts'::
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## 使用 `redux-observable` 编写异步流
+
+### epics 类型声明
+
+::codeblock='playground/src/features/todos/epics.ts'::
+
+[⇧ 返回顶部](#目录)
+
+### 测试 epics
+
+::codeblock='playground/src/features/todos/epics.spec.ts'::
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## 使用 `reselect` 生成 Selectors
+
+::codeblock='playground/src/features/todos/selectors.ts'::
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## 使用 `react-redux` 的 connect 方法
+
+### 连接组件类型声明
+
+*__注意__:在下面一段代码中,只有关于 connect 类型声明背后概念的简短说明。请查看 [Redux 连接组件](#redux-%e8%bf%9e%e6%8e%a5%e7%bb%84%e4%bb%b6) 章节了解更多更具体的例子*
+
+```tsx
+import MyTypes from 'MyTypes';
+
+import { bindActionCreators, Dispatch, ActionCreatorsMapObject } from 'redux';
+import { connect } from 'react-redux';
+
+import { countersActions } from '../features/counters';
+import { FCCounter } from '../components';
+
+// Type annotation for "state" argument is mandatory to check
+// the correct shape of state object and injected props you can also
+// extend connected component Props interface by annotating `ownProps` argument
+const mapStateToProps = (state: MyTypes.RootState, ownProps: FCCounterProps) => ({
+ count: state.counters.reduxCounter,
+});
+
+// "dispatch" argument needs an annotation to check the correct shape
+// of an action object when using dispatch function
+const mapDispatchToProps = (dispatch: Dispatch) =>
+ bindActionCreators({
+ onIncrement: countersActions.increment,
+ }, dispatch);
+
+// shorter alternative is to use an object instead of mapDispatchToProps function
+const dispatchToProps = {
+ onIncrement: countersActions.increment,
+};
+
+// Notice we don't need to pass any generic type parameters to neither
+// the connect function below nor map functions declared above
+// because type inference will infer types from arguments annotations automatically
+// This is much cleaner and idiomatic approach
+export const FCCounterConnected =
+ connect(mapStateToProps, mapDispatchToProps)(FCCounter);
+
+// You can add extra layer of validation of your action creators
+// by using bindActionCreators generic type parameter and RootAction type
+const mapDispatchToProps = (dispatch: Dispatch) =>
+ bindActionCreators>({
+ invalidActionCreator: () => 1, // Error: Type 'number' is not assignable to type '{ type: "todos/ADD"; payload: Todo; } | { ... }
+ }, dispatch);
+
+```
+
+### 连接组件类型声明,并集成 `redux-thunk`
+
+*__注意__:使用 thunk action creators 时你需要使用 `bindActionCreators`。只有这样,你才能获得正确的 dispatch props 类型签名,如下所示。*
+
+*__警告__: 目前(2019 四月)最新版 `redux-thunk` 中的 `bindActionCreators` 签名不会像下面那样正常工作,你需要使用 [`/playground/typings/redux-thunk/index.d.ts`](./playground/typings/redux-thunk/index.d.ts) 中改良的类型定义并覆写 tsconfig 中的 `paths` 字段,像这样: [`"paths":{"redux-thunk":["typings/redux-thunk"]}`](./playground/tsconfig.json)。*
+
+```tsx
+const thunkAsyncAction = () => async (dispatch: Dispatch): Promise => {
+ // dispatch actions, return Promise, etc.
+}
+
+const mapDispatchToProps = (dispatch: Dispatch) =>
+ bindActionCreators(
+ {
+ thunkAsyncAction,
+ },
+ dispatch
+ );
+
+type DispatchProps = ReturnType;
+// { thunkAsyncAction: () => Promise; }
+
+/* Without "bindActionCreators" fix signature will be the same as the original "unbound" thunk function: */
+// { thunkAsyncAction: () => (dispatch: Dispatch) => Promise; }
+```
+
+[⇧ 返回顶部](#目录)
+
+---
+
+# 配置和开发者工具
+
+## 通用 Npm Scripts
+> 通用的、跨项目的、 TS 相关的 npm scripts
+```
+"prettier": "prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)",
+"prettier:fix": "prettier --write 'src/**/*.ts'",
+"lint": "tslint -p ./",
+"tsc": "tsc -p ./ --noEmit",
+"tsc:watch": "tsc -p ./ --noEmit -w",
+"test": "jest --config jest.config.json",
+"test:watch": "jest --config jest.config.json --watch",
+"test:update": "jest --config jest.config.json -u"
+"ci-check": "npm run prettier && npm run lint && npm run tsc && npm run test",
+```
+
+[⇧ 返回顶部](#目录)
+
+## tsconfig.json
+
+我们有推荐的 `tsconfig.json` 配置文件,你可以借助 [`react-redux-typescript-scripts`](https://github.com/piotrwitek/react-redux-typescript-scripts) 方便地把它添加到你的项目里。
+
+::expander='playground/tsconfig.json'::
+
+[⇧ 返回顶部](#目录)
+
+## TSLib
+https://www.npmjs.com/package/tslib
+
+这个库通过把运行时辅助函数外置化,而不是内嵌到每个文件中,来减少你的打包文件大小。
+
+> 安装
+`npm i tslib`
+
+把这行加到你的 `tsconfig.json` 中:
+```ts
+"compilerOptions": {
+ "importHelpers": true
+}
+```
+
+[⇧ 返回顶部](#目录)
+
+## TSLint
+https://palantir.github.io/tslint/
+
+> 安装
+`npm i -D tslint`
+
+> 如果用于 React 项目,你应该加上额外的 `react` 规则集:`npm i -D tslint-react` https://github.com/palantir/tslint-react
+
+我们有推荐配置文件,你可以借助 [`react-redux-typescript-scripts`](https://github.com/piotrwitek/react-redux-typescript-scripts) 方便地把它添加到你的项目里。
+
+#### tslint.json
+::expander='playground/tslint.json'::
+
+[⇧ 返回顶部](#目录)
+
+## ESLint
+https://eslint.org/
+https://typescript-eslint.io
+
+> 安装
+`npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin`
+
+我们有推荐配置文件,他会自动添加 TypeScript 的解析器和插件,你可以借助 [`react-redux-typescript-scripts`](https://github.com/piotrwitek/react-redux-typescript-scripts) 方便地把它添加到你的项目里。
+
+#### .eslintrc
+::expander='playground/.eslintrc'::
+
+[⇧ 返回顶部](#目录)
+
+## Jest
+https://jestjs.io/
+
+> 安装
+`npm i -D jest ts-jest @types/jest`
+
+#### jest.config.json
+::expander='configs/jest.config.json'::
+
+#### jest.stubs.js
+::expander='configs/jest.stubs.js'::
+
+[⇧ 返回顶部](#目录)
+
+## 风格指南
+
+### ["react-styleguidist"](https://github.com/styleguidist/react-styleguidist)
+
+[⟩⟩⟩ styleguide.config.js](/playground/styleguide.config.js)
+
+[⟩⟩⟩ demo](https://piotrwitek.github.io/react-redux-typescript-guide/)
+
+[⇧ 返回顶部](#目录)
+
+---
+
+# 食谱
+
+### 通用小贴士
+
+#### - 使用 TS 时我还需要使用 React.PropTypes 吗?
+不。用了 TypeScript 之后,没有必要再使用 PropTypes。当声明 Props 和 State 接口后,你将通过静态类型检查获得完全的自动补全和编码时的安全性。这样,你就能直接避免运行时错误,并减少大量调试时间。额外的好处是,这也是一种用于在源码中解释组件公共 API 的优雅而标准化的方法。
+
+[⇧ 返回顶部](#目录)
+
+#### - 什么时候使用 `interface` 声明,什么时候使用 `type` 别名?
+从实际来看,使用 `interface` 声明在编译错误时会生成一个 interface 同名标识,相反 `type` 别名不会生成标识名,并且会展开显示所有属性和嵌套的类型。
+尽管我大部分时候更喜欢用 `type` ,但是有时候编译错误过于冗长影响排查,我会根据两者的差别,改用 interface 来隐藏报错中没那么重要的类型细节。
+相关的 `ts-lint` 规则:https://palantir.github.io/tslint/rules/interface-over-type-literal/
+
+[⇧ 返回顶部](#目录)
+
+#### - 具名 exports 和 default export 那个比较好?
+一个常见的适应性方案是使用文件夹模块模式,这样你可以根据情况同时使用具名和默认 import。
+这个方案的好处是你能实现更好的封装,以及能够安全地重构内部命名和文件夹结构,而不影响你的业务代码:
+
+```ts
+// 1. create your component files (`select.tsx`) using default export in some folder:
+
+// components/select.tsx
+const Select: React.FC = (props) => {
+...
+export default Select;
+
+// 2. in this folder create an `index.ts` file that will re-export components with named exports:
+
+// components/index.ts
+export { default as Select } from './select';
+...
+
+// 3. now you can import your components in both ways, with named export (better encapsulation) or using default export (internal access):
+
+// containers/container.tsx
+import { Select } from '@src/components';
+or
+import Select from '@src/components/select';
+...
+```
+
+[⇧ 返回顶部](#目录)
+
+#### - 什么是初始化 class 实例或静态属性的最佳实践?
+首选新语法来进行 class 属性初始化
+```tsx
+class ClassCounterWithInitialCount extends React.Component {
+ // default props using Property Initializers
+ static defaultProps: DefaultProps = {
+ className: 'default-class',
+ initialCount: 0,
+ };
+
+ // initial state using Property Initializers
+ state: State = {
+ count: this.props.initialCount,
+ };
+ ...
+}
+```
+
+[⇧ 返回顶部](#目录)
+
+#### - 什么是声明组件 handler 方法的最佳实践?
+首选新语法,用箭头函数声明 class 方法字段
+```tsx
+class ClassCounter extends React.Component {
+// handlers using Class Fields with arrow functions
+ handleIncrement = () => {
+ this.setState({ count: this.state.count + 1 });
+ };
+ ...
+}
+```
+
+[⇧ 返回顶部](#目录)
+
+### module 环境声明小贴士
+(译注:[环境声明(ambient)](https://jkchao.github.io/typescript-book-chinese/typings/ambient.html) 和 [模块扩展(augmentation)](https://www.tslang.cn/docs/handbook/declaration-merging.html))
+#### 环境声明中的 imports
+若要进行 module 扩展,import 应该位于 module 声明外部。
+```ts
+import { Operator } from 'rxjs/Operator';
+import { Observable } from 'rxjs/Observable';
+
+declare module 'rxjs/Subject' {
+ interface Subject {
+ lift(operator: Operator): Observable;
+ }
+}
+```
+
+创建第三方类型定义时,所有 imports 应该位于 module 声明内部,否则 imports 将被视为扩展并报错。
+
+```ts
+declare module "react-custom-scrollbars" {
+ import * as React from "react";
+ export interface positionValues {
+ ...
+```
+
+[⇧ 返回顶部](#目录)
+
+### 类型定义小贴士
+
+#### 缺少类型定义的错误
+如果你找不到第三方模块的类型声明,你可以自己写一个,或借助 [Shorthand Ambient Modules](https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#shorthand-ambient-modules) 禁用该模块的类型检查。
+
+::codeblock='playground/typings/modules.d.ts'::
+
+#### 为 npm 模块使用自定义 `d.ts` 文件
+如果你想为(自带类型定义的)某些 npm 模块使用替代的(自定义的)类型定义,你可以通过覆写编译选项中 `paths` 字段来实现。
+
+```ts
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "redux": ["typings/redux"], // use an alternative type-definitions instead of the included one
+ ...
+ },
+ ...,
+ }
+}
+```
+
+[⇧ 返回顶部](#目录)
+
+### 类型扩展小贴士
+外部类型定义文件(*.d.ts)相关问题的处理策略
+
+#### 对库的内部声明进行扩展 - 使用相对路径 import
+
+```ts
+// added missing autoFocus Prop on Input component in "antd@2.10.0" npm package
+declare module '../node_modules/antd/lib/input/Input' {
+ export interface InputProps {
+ autoFocus?: boolean;
+ }
+}
+```
+
+#### 对库的公开声明进行扩展 - 使用 node_modules import
+
+```ts
+// fixed broken public type-definitions in "rxjs@5.4.1" npm package
+import { Operator } from 'rxjs/Operator';
+import { Observable } from 'rxjs/Observable';
+
+declare module 'rxjs/Subject' {
+ interface Subject {
+ lift(operator: Operator): Observable;
+ }
+}
+```
+
+> 更多搭配第三方类型定义的进阶场景可以在 [TypeScript 官方文档](https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#working-with-other-javascript-libraries) 找到
+
+[⇧ 返回顶部](#目录)
+
+---
+
+## 教程和文章
+> 相关进阶教程精选清单
+
+高阶组件:
+- https://medium.com/@jrwebdev/react-higher-order-component-patterns-in-typescript-42278f7590fb
+
+[⇧ 返回顶部](#目录)
+
+---
+
+
+## 贡献者
+
+感谢这些优秀的人 ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
+
+
+
+| [
Piotrek Witek](https://github.com/piotrwitek)
[💻](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=piotrwitek "Code") [📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=piotrwitek "Documentation") [🤔](#ideas-piotrwitek "Ideas, Planning, & Feedback") [👀](#review-piotrwitek "Reviewed Pull Requests") [💬](#question-piotrwitek "Answering Questions") | [
Kazz Yokomizo](https://github.com/kazup01)
[💵](#financial-kazup01 "Financial") [🔍](#fundingFinding-kazup01 "Funding Finding") | [
Jake Boone](https://github.com/jakeboone02)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=jakeboone02 "Documentation") | [
Amit Dahan](https://github.com/amitdahan)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=amitdahan "Documentation") | [
gulderov](https://github.com/gulderov)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=gulderov "Documentation") | [
Erik Pearson](https://github.com/emp823)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=emp823 "Documentation") | [
Bryan Mason](https://github.com/flymason)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=flymason "Documentation") |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| [
Jakub Chodorowicz](http://www.jakub.chodorowicz.pl/)
[💻](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=chodorowicz "Code") | [
Oleg Maslov](https://github.com/mleg)
[🐛](https://github.com/piotrwitek/react-redux-typescript-guide/issues?q=author%3Amleg "Bug reports") | [
Aaron Westbrook](https://github.com/awestbro)
[🐛](https://github.com/piotrwitek/react-redux-typescript-guide/issues?q=author%3Aawestbro "Bug reports") | [
Peter Blazejewicz](http://www.linkedin.com/in/peterblazejewicz)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=peterblazejewicz "Documentation") | [
Solomon White](https://github.com/rubysolo)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=rubysolo "Documentation") | [
Levi Rocha](https://github.com/pino)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=pino "Documentation") | [
Sudachi-kun](http://cloudnative.co.jp)
[💵](#financial-loadbalance-sudachi-kun "Financial") |
+| [
Sosuke Suzuki](http://sosukesuzuki.github.io)
[💻](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=sosukesuzuki "Code") | [
Tom Rathbone](https://github.com/chillitom)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=chillitom "Documentation") | [
Arshad Kazmi](https://arshadkazmi42.github.io/)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=arshadkazmi42 "Documentation") | [
JeongUkJae](https://jeongukjae.github.io)
[📖](https://github.com/piotrwitek/react-redux-typescript-guide/commits?author=JeongUkJae "Documentation") |
+
+
+这个项目遵循 [all-contributors](https://github.com/kentcdodds/all-contributors) 规范。欢迎任意形式的贡献!
+
+---
+
+MIT License
+
+Copyright (c) 2017 Piotr Witek (http://piotrwitek.github.io)
diff --git a/package.json b/package.json
index f23828e..aa42243 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
},
"scripts": {
"ci-check": "npm run doctoc && npm run readme:generate",
- "doctoc": "doctoc --maxlevel=3 README_SOURCE.md",
+ "doctoc": "doctoc --maxlevel=3 README_SOURCE.md README_SOURCE-zh.md",
"readme:generate": "node generate-readme",
"contributors:check": "all-contributors check",
"contributors:add": "all-contributors add",