在 React 中使用 TypeScript

Create React App 内置了对 TypeScript 的支持。
需要创建一个使用 TypeScript 的新项目,在终端运行:
npx create-react-app my-app --template typescriptReact 中,你的组件文件大多数使用 .js 作为扩展名。在 TypeScript 中,提供两种文件扩展名:
.ts 是默认的文件扩展名,而 .tsx 是一个用于包含 JSX 代码的特殊扩展名。
类型定义
为了能够显示来自其他包的错误和提示,编译器依赖于声明文件。声明文件提供有关库的所有类型信息。这样,我们的项目就可以用上像 npm 这样的平台提供的三方 JavaScript 库。
获取一个库的声明文件有两种方式:
Bundled - 该库包含了自己的声明文件。这样很好,因为我们只需要安装这个库,就可以立即使用它了。要知道一个库是否包含类型,看库中是否有 index.d.ts 文件。有些库会在 package.json 文件的 typings 或 types 属性中指定类型文件。
DefinitelyTyped - DefinitelyTyped 是一个庞大的声明仓库,为没有声明文件的 JavaScript 库提供类型定义。这些类型定义通过众包的方式完成,并由微软和开源贡献者一起管理。例如,React 库并没有自己的声明文件。但我们可以从 DefinitelyTyped 获取它的声明文件。只要执行以下命令。
# yarnyarn add --dev @types/react# npmnpm i --save-dev @types/react
局部声明 - 有时,你要使用的包里没有声明文件,在 DefinitelyTyped 上也没有。在这种情况下,我们可以创建一个本地的定义文件。因此,在项目的根目录中创建一个 declarations.d.ts 文件。一个简单的声明可能是这样的:
declare module 'querystring' {export function stringify(val: object): stringexport function parse(val: string): object}
现在已做好编码准备了!下面开始项目实战来了解有关 TypeScript 的更多知识:
// store.tsximport { createStore, applyMiddleware, StoreEnhancer, StoreEnhancerStoreCreator, Store } from 'redux'import thunk from 'redux-thunk'import reducer from './reducers'let storeEnhancer:StoreEnhancer = applyMiddleware(thunk)let storeEnhancerStoreCreator:StoreEnhancerStoreCreator = storeEnhancer(createStore)let store: Store = storeEnhancerStoreCreator(reducer)export default store
// reducers/index.tsximport { combineReducers, ReducersMapObject, AnyAction, Reducer } from 'redux'import counter, { CounterState} from './count'//接口其实就是定义合并后的状态export interface CombinedState {counter1: CounterState}let reducers:ReducersMapObject<CombinedState, AnyAction> = {counter1: counter}let reducer:Reducer<CombinedState, AnyAction> = combineReducers(reducers)export default reducer
// reducers/count.tsximport { AnyAction } from "redux";export interface CounterState {count: number}const initialState: CounterState = {count: 0}export default function reducer(state: CounterState = initialState, action: AnyAction): CounterState {console.log(action)switch (action.type) {case 'ADD':return { count: state.count + 1 }default:return state}}
// index.tsximport React from 'react';import ReactDOM from 'react-dom';import './index.css';import Counter from './components/Counter';import reportWebVitals from './reportWebVitals';import { Provider } from 'react-redux'import store from './store'ReactDOM.render(<Provider store={store}><Counter /></Provider>,document.getElementById('root'))
// components/Counter.tsximport React from 'react'import { Dispatch } from 'redux'import { connect } from 'react-redux'import { CounterState } from '../store/reducers/count'import { CombinedState } from '../store/reducers'let mapStateToProps = (state:CombinedState):CounterState => state.counter1let mapDispatchToProps = (dispatch: Dispatch) => {return {add () { dispatch({ type: 'ADD' }) }}}type Props = ReturnType<typeof mapStateToProps> & ReturnType<typeof mapDispatchToProps>class Counter extends React.Component<Props> {render () {return (<div><button onClick={() => this.props.add()}>加</button><div>{this.props.count}</div></div>)}}export default connect(mapStateToProps, mapDispatchToProps)(Counter)
创建 store 状态管理我们需要安装的包:
npm i react-redux redux-thunk --savenpm i @types/react-redux --save-dev简单的代码演示介绍到这里,你学会了吗?
