在 React 中使用 TypeScript

前端精髓

共 3597字,需浏览 8分钟

 · 2021-03-16


Create React App 内置了对 TypeScript 的支持。


需要创建一个使用 TypeScript 的新项目,在终端运行:

npx create-react-app my-app --template typescript


React 中,你的组件文件大多数使用 .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): string  export function parse(val: string): object}


现在已做好编码准备了!下面开始项目实战来了解有关 TypeScript 的更多知识:



// store.tsx
import { 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.tsx
import { 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.tsx
import { 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.tsx
import 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.tsx
import 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 --save
npm i @types/react-redux --save-dev


简单的代码演示介绍到这里,你学会了吗?


浏览 94
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报