Typescript-react相关类型

2,153 阅读4分钟

react相关类型

react自带常用类型

FunctionComponent<P={}>

简写FC<P={}>,无状态组件(SFC),函数组件的类型定义,一个泛型接口,可以接受一个参数,可以不传,用来定义props的类型。

interface EditorsProps {
	detail: string
}
// const Editors:React.FunctionComponent<EditorsProps> = (props) => {
const Editors: React.FC<EditorsProps> = (props) => {
	const { detail } = props;
	return (<>{detail}</>);
};
Component<P,S={}>/PureComponent<P,S={}>

泛型类,接收两个参数,第一个是props的类型定义,第二个是state的类型定义(可以省略,但当有父组件传递属性方法或者定义state的时候还是需要,当没有的情况下省去,和不用TypeScript使用一样),例如下面的例子

import React, { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom';
interface CountProps extends RouteComponentProps {//可以继承其它的接口类型
	count: number;
	asyncAddCount: (count: number) => void;
	asyncReduceCount: (count: number) => void;
}
interface CountStateType{//当需要的时候才定义
}
class Counter extends Component<CountProps, CountStateType> {
	render(): JSX.Element{
		const { count, asyncAddCount, asyncReduceCount } = this.props;
		return (
			<div>
				<h2>{count}</h2>
				<button onClick={asyncAddCount.bind(null, 10)}>Counter++</button>
				<button onClick={asyncReduceCount.bind(null, 10)}>Counter--</button>
			</div>
		)
	}
}
JSX.Element

return返回的jsx语法类型,例如上述的render中return的就是这个类型。

ComponentClass<P,S={}>

类的类型,泛型接口,可以在高阶组件中使用,当接收一个类或者函数的时候。

import React, { Context, FC, ComponentClass, createContext, useReducer } from 'react';

const ProviderContext: Context<any> = createContext('provider');

export default const RootProvider = (reducer: Function, initialState: any) => (Com: FC<any> | ComponentClass<any,any>) => {
  return () => {
    const [state, dispatch] = useReducer<any>(reducer, initialState);
    return (
      <ProviderContext.Provider value={{ state, dispatch }}>
        <Com />
      </ProviderContext.Provider >
    );
  }
}
Context

context的类型就是他的本身,一个泛型接口。

//源码的类型定义如下:可以发现我们需要传递一个类型,从而使得里面的参数类型也是一致
interface Context<T> {
	Provider: Provider<T>;
	Consumer: Consumer<T>;
	displayName?: string;
}
Dispatch<any>

泛型接口,用于定义dispatch的类型,常常用于useReducer生成的dispatch中。

// 创建一个异步action的函数,返回一个包含异步action对象
const asyncAction = (dispatch: Dispatch<any>) => {
  return {
    asyncAddaction() {
      console.log('执行addActions之前: ' + Date.now());
      setTimeout(() => {
        console.log('执行addActions : ' + Date.now());
        dispatch(addActions());
      }, 1000);
    }
  }
}
FormEvent

一个react的form表单event的类型。

<form 
	onSubmit={(e:FormEvent)=>{
		e.preventDefault();
}}></form>
ChangeEvent

react的onChange事件触发的event类型,这是一个泛型接口,使用如下:

<input 
	type="text" 
	value={count} 
	onChange={(e: ChangeEvent<HTMLInputElement>) => {
		setCount(e.currentTarget.value);//HTMLInputElement表示这个一个html的input节点
}} />

可选泛型类型:HTMLSelectElementHTMLInputElementHTMLDivElementHTMLTextAreaElement等html标签的所有类型节点。 还有其他各种事件处理类型,可以在@types/react中查看。

SyntheticEvent<T = Element, E = Event>

泛型接口,事件包装器,即原生事件的集合,就是原生事件的组合体。

您的事件处理程序将传递 SyntheticEvent 的实例,这是一个跨浏览器原生事件包装器。(官方介绍)

<button onClick={(e:SyntheticEvent<Element, Event>)=>{}}></button>
<input onChange={(e:SyntheticEvent<Element, Event>)=>{}}/>
<form
	onSubmit={(e: SyntheticEvent<Element, Event>) => {}}
	onBlur={(e: SyntheticEvent<Element, Event>) => {}}
	onKeyUp={(e: SyntheticEvent<Element, Event>) => {}}
>
</form>

从上面可以发现,合成事件的泛型接口在任意事件上都能适用。

LazyExoticComponent

lazy懒加载的类型,泛型接口,可以接受各种类型的参数,视情况而定,例如:

export interface RouteType {
  pathname: string;
  component: LazyExoticComponent<any>;
  exact: boolean;
  title?: string;
  icon?: string;
  children?: RouteType[];
}
export const AppRoutes: RouteType[] = [
  {
    pathname: '/login',
    component: lazy(() => import('../views/Login/Login')),
    exact: true
  },
  {
    pathname: '/404',
    component: lazy(() => import('../views/404/404')),
    exact: true,
  },
  {
    pathname: '/',
    exact: false,
    component: lazy(() => import('../views/Admin/Admin'))
  }
]
RefForwardingComponent<T, P = {}>

forwardRef,ref转发的类型定义,泛型接口,接收两个参数。

forwardRef(Editors) as RefForwardingComponent<any, any>;
//分别是ref的类型和props的类型,为了简单可以都定义为any
//源码类型定义如下
 interface RefForwardingComponent<T, P = {}> {
	(props: PropsWithChildren<P>, ref: Ref<T>): ReactElement | null;
	propTypes?: WeakValidationMap<P>;/
	contextTypes?: ValidationMap<any>;
	defaultProps?: Partial<P>;
	displayName?: string;
 }
MutableRefObject<any>

泛型接口,接收一个参数,作为useRef的类型定义,参数可以为任意类型。

const prctureRef: React.MutableRefObject<any> = useRef();
useState<any>

hooks的useState是一个泛型函数,可以传递一个类型来定义这个hooks。

const [isShowAdd, setIsShowAdd] = useState<boolean>(false);

当然useRef也是一个泛型函数,如果想要严谨的话也可以传递给一个类型来定义,还有useReducer等都差不多。

react-router的常用类型

RouteComponentProps

最常见的路由api的类型定义,里面包含了history,location,match,staticContext这四个路由api的类型定义

import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
export default function Admin({ history, location, match }: RouteComponentProps) {
	return(<>这是主页</>);
}

Antd的类型定义

FormComponentProps

用于Form组件的使用

import React from 'react';
import { Form } from 'antd';
import { FormComponentProps } from 'antd/lib/form';
interface AddFormProps extends FormComponentProps {
}
function AddForm({ form }: AddFormProps) {
	return (
		<Form></Form>
	);
}
export default Form.create()(AddForm) as any;

里面的form的类型是WrappedFormUtils<any>泛型接口,正常在对form赋值的时候的定义。

ColumnProps<any>

表格定义的columns属性的每一项的类型,参数any表示表格数据的类型,示例如下:

interface ProductType {
  key:string;
  name:string;
  desc:string
}
const columns: ColumnProps<ProductType>[] = [
  {
    title: '商品名称',
    dataIndex: 'name'
  },
  {
    title: '商品详情',
    dataIndex: 'desc'
  }
]

其他

Promise<any>

参数any表示promise返回数据的类型

interface IResponse<T> {
  message: string,
  result: T,
  success: boolean,
}
async function getResponse (): Promise<IResponse<number[]>> {
  return {
    message: '获取成功',
    result: [1, 2, 3],
    success: true,
  }
}
getResponse()
  .then(response => {
    console.log(response.result)
  })
axios
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
const server: AxiosInstance = axios.create();
server.interceptors.request.use((config: AxiosRequestConfig) => {//请求拦截
    return config;
});
server.interceptors.response.use((res: AxiosResponse) => {
    if (res.status === 200) {
        res = res.data;
    }
    return res;
},(err:AxiosError)=>{});