注意:不用清除的看懂代码,只需要了解类型即可,或者观看我其它博客可以有相应的介绍等
FunctionComponent、简写FC
一个泛型接口,可以接受一个参数,可以不传,用来定义props的类型interface EditorsProps {
detail: string
}
//const Editors: React.FunctionComponent = () => {
const Editors: React.FC<props: EditorsProps> = () => {
const { detail } = props;
return (<></>);
};
Component/PureComponent
泛型类,接收两个参数,第一个是props的类型定义,第二个是state的类型定义,例如下面的例子(但当有父组件传递属性方法或者定义state的时候还是需要,当没有的情况下省去,和不用TypeScript试用试用一样)import React, { Component } from 'react'
import { connect } from 'react-redux';
import { asyncAddCount, asyncReduceCount } from '../../store/actions';
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>
)
}
}
export default connect(
(state: any) => ({ count: state.getIn(['countReducer', 'count']) }),
{ asyncAddCount, asyncReduceCount }
)(Counter);
JSX.Element
return返回的jsx语法类型,例如上述的render中return的就是这个类型类的类型就是:ComponentClass泛型接口,可以在高阶组件中使用,当接收一个类或者函数的时候
import React, { Context,FC,ComponentClass, createContext, useReducer } from 'react';
const ProviderContext: Context<any> = createContext('provider');
export default (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 >
);
}
}
Dispatch
泛型接口,用于定义dispatch的类型,常常用于useReducer生成的dispatch中// 创建一个异步action的函数,返回一个包含异步action对象
const asyncAction = (dispatch: Dispatch<any>) => {
return {
asyncAddaction() {//这是一个异步的添加action,定时器模拟异步
console.log('执行addActions之前: ' + Date.now());//打印一下时间
setTimeout(() => {
console.log('执行addActions : ' + Date.now());
dispatch(addActions());//执行同步action
}, 1000);
}
}
}
const ProviderContext: Context = createContext('provider');中也可以发现,context的类型就是他的本身,一个泛型接口
//源码的类型定义如下:可以发现我们需要传递一个类型,从而使得里面的参数类型也是一致
interface Context<T> {
Provider: Provider<T>;
Consumer: Consumer<T>;
displayName?: string;
}
FormEvent
:一个react的form表单event的类型,正常结合antd的Form表单使用<form
onSubmit={(e:FormEvent)=>{
e.preventDefault();//取消默认事件
}}>
ChangeEvent:
react的onChange事件触发的event类型,这是一个泛型接口,使用如下:<input
type="text"
value={count}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
setCount(e.currentTarget.value);//HTMLInputElement表示这个一个html的input节点
}} />
HTMLSelectElement、HTMLInputElement、HTMLDivElement、HTMLTextAreaElement等html标签的所有类型节点
SyntheticEvent
泛型接口,即原生事件的集合,就是原生事件的组合体您的事件处理程序将传递 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
泛型接口,可以接受各种类型的参数,视情况而定,例如: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
泛型接口,接收两个参数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
泛型接口,接收一个参数,作为useRef的类型定义,参数可以为T类型,即任意类型const prctureRef: React.MutableRefObject<any> = useRef();
useState
hooks的useState是一个泛型函数,可以传递一个类型来定义这个hooks,当然useRef也是一个泛型函数,如果想要严谨的话也可以传递给一个类型来来定义
,还有useReducer
等都差不多//例如:
const [isShowAdd, setIsShowAdd] = useState<boolean>(false);
其余的类型都是自定义类型,和萌新我暂时不知道的了,有发现就来更新?
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作为蚂蚁金服用Typescript制作的一个UI框架来说,对Typescript的支持还是很友好的,萌新我就先说一下我知道的一些类型
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;
WrappedFormUtils
泛型接口,正常在对form赋值的时候的定义ColumnProps
,参数any正常选表格的数据数组的类型,例如user的类型是UserType则就是ColumnProps,示例如下:const columns: ColumnProps<ProductType>[] = [
{
title: '商品名称',
dataIndex: 'name'
},
{
title: '商品详情',
dataIndex: 'desc'
}
]
CascaderOptionType
类型,例如:import React,{useState} from 'react';
import { Cascader } from 'antd';
import { CascaderOptionType } from 'antd/lib/cascader';
const CascaderTest:FC = () => {
const [options, setOptions] = useState<Array<CascaderOptionType>>(initialOptions);
const loadData = (selectedOptions: CascaderOptionType[] | undefined) => {}
return (<Cascader
options={options}//级联的数据
loadData={loadData}// 调用这个回调函数加载下一级列表的数据
/>);
}
UploadFile
用来定义文件对象的类型,UploadFileStatus文件类型常量(antd内部源码使用)//export declare type UploadFileStatus = 'error' | 'success' | 'done' | 'uploading' | 'removed';
import React from 'react';
import { Upload, Icon } from 'antd';
import { UploadFile,UploadFileStatus } from 'antd/lib/upload/interface';
function PricturesWall():JSX.Element {
const uploadButton = (
<div>
<Icon type="plus" style={{ fontSize: '25px' }} />
<div className="ant-upload-text">图片上传</div>
</div>
);
const fileList:UploadFile[] = [
{
uid: - index,//唯一标识
name: img,//图片文件名
status: DONE,//图片状态 : 已上传完成
url: BASE_IMG_URL + img//图片地址
}
];
return(<Upload
fileList={fileList}//所有已经上传文件对象的数组
>
{fileList.length > 3 ? null : uploadButton}
</Upload>);
}
(使用axios,往往会想到的是请求拦截和响应拦截,下面就是请求和响应的类型,以及创建一个axios的类型、还有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)=>{});
具体的axios类型:
import InterceptorManger from "../core/interceptorManger";
/**
* method请求类型的类型
*/
export type Method = 'get' | 'GET' | 'POST' | 'post' | 'delete' | 'DELETE' | 'PUT' | 'put' | 'HEAD' | 'head' | 'options' | 'OPTIONS' | 'patch' | 'PATCH';
/**
* axios发送的的数据格式
*/
export interface AxiosRequestConfig {
url?: string;
method?: Method;
data?: any;
params?: any;
headers?: any;
responseType?: XMLHttpRequestResponseType; // 设置响应的数据类型
timeout?: number;// 超时时间
/**
* baseURL 设置后在请求前面会自动拼接上这个url
*/
baseURL?: string;
/**
* 添加两个能在axios请求发送前的时候修改data的函数|函数数组
*/
transformRequest?: AxiosTransformer | AxiosTransformer[];
/**
* 添加两个能在axios响应数据获取的时候修改data的函数|函数数组
*/
transformResponse?: AxiosTransformer | AxiosTransformer[];
/**
* canceltoken 取消token可选属性
*/
cancelToken?: CancelToken;
/**
* withCredentials 用于请求携带后端那边的cookies
*/
withCredentials?: boolean;
/**
* xsrf防止跨域伪造的cookie名
*/
xsrfCookieName?: string;
/**
* xsrf防止跨域伪造的header名
*/
xsrfHeaderName?: string;
/**
* 下载进度监控
*/
onDownloadProgress?: (e: ProgressEvent) => void;
/**
* 上传进度监控
*/
onUploadProgress?: (e: ProgressEvent) => void;
/**
* 安全配置auth属性,接收一个AxiosBasicCredentials类型的对象
*/
auth?: AxiosBasicCredentials;
/**
* 配置合法的请求状态码区域,默认是[200-300)之间合法,可以自行配置,
* 接收一个参数status
*/
validateStatus?: (status: number) => boolean;
/**
* params序列化的函数
*/
paramsSerializer?: (params: any) => string;
// 添加索引签名,可以传入什么key和什么value都行
[propName: string]: any;
}
/**
* transformRequest类型和transformResponse类型
*/
export interface AxiosTransformer {
(data: any, headers?: any): any;
}
/**
* axios响应的数据格式
*/
export interface AxiosResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: any;
config: AxiosRequestConfig;
request: any;
}
/**
* 响应的promise类型
*/
export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> { }
/**
* 响应的错误信息接口
*/
export interface AxiosError extends Error {
isAxiosError: boolean;
config: AxiosRequestConfig;
code?: string | null;
request?: any;
response?: AxiosResponse;
}
/**
* 一个整个axios类的接口
*/
export interface Axios {
defaults: AxiosRequestConfig;
interceptors: AxiosInterceptors;
/** 和axios本身调用一样 */
request<T = any>(url: AxiosRequestConfig | string, config?: AxiosRequestConfig): AxiosPromise<T>;
/** get请求 */
get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
/** delete请求 */
delete<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
/** head请求 */
head<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
/** options请求 */
options<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
/** post请求 */
post<T = any>(url: string, data?: T, config?: AxiosRequestConfig): AxiosPromise<T>;
/** put请求 */
put<T = any>(url: string, data?: T, config?: AxiosRequestConfig): AxiosPromise<T>;
/** patch请求 */
patch<T = any>(url: string, data?: T, config?: AxiosRequestConfig): AxiosPromise<T>;
/**
* 获取config中的url的方法,
* @param config config配置对象
*/
getUri(config?: AxiosRequestConfig): string;
}
/**
* axios的实例接口类型
*/
export interface AxiosInstance extends Axios {
// 继承Axios接口,并实现一个默认调用方法,同时对默认调用方法进行方法重载
<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;
<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
}
/**
* axios的类静态类型
*/
export interface AxiosClassStatic {
new(config: AxiosRequestConfig): Axios;
}
/**
* axios的扩展接口类型
*/
export interface AxiosStatic extends AxiosInstance {
/**
* 该扩展方法执行后创建一个AxiosInstance
* @param config 这个默认配置可以传可以不传
*/
create(config?: AxiosRequestConfig): AxiosInstance;
// 扩展取消的方法和属性
/**
* CancelToken属性,CancelToken的类类型,用来实例化CancelToken类的
*/
CancelToken: CancelTokenStatic;
/**
* Cancel属性,Cancel的类类型,用来实例化Cancel类
*/
Cancel: CancelStatic;
/**
* 判断取消是否成功的方法
*/
isCancel: (val: any) => boolean;
/**
* all方法,对多个axios请求进行合并,和promise.all一致功能,
* 接收一个到多个axios请求的promise
*/
all<T>(promises: Array<T | Promise<T>>): Promise<T[]>;
/**
* 接收多个promise的then结果,返回一个callback,里面有多个promise执行的结果,
* 返回一个函数,函数参数是数组
*/
spread<T, R>(callback: (...args: T[]) => R): (arr: T[]) => R;
/**
* 一个Axios,是Axios的实例对象类型
*/
Axios: AxiosClassStatic;
}
/**
* 拦截器的类型
*/
export interface AxiosInterceptors {
// InterceptorManger是下面AxiosInterceptorManager的实现类
request: InterceptorManger<AxiosRequestConfig>;
response: InterceptorManger<AxiosResponse>;
}
/**
* axios的拦截器管理类型
*/
export interface AxiosInterceptorManager<T> {
/**
* 绑定拦截器,返回一个拦截器id
* @param resolved resolve方法,必传参数
* @param rejected reject错误方法,可选参数
*/
use(resolved: ResolvedFn<T>, rejected?: RejectedFn): number;
/**
* 通过拦截器删除一个接口
* @param id 需要删除的拦截器的id
*/
eject(id: number): void;
}
/**
* 请求拦截器和响应拦截器类型不一致,所以这时候的resolve回调函数类型
*/
export interface ResolvedFn<T> {
(val: T): T | Promise<T>; // 这个方法返回可以promise也可以是正常类型
}
/**
* reject回调函数类型,请求拦截器和响应拦截器类型不一致
*/
export interface RejectedFn {
(val: any): any; // 这个方法返回可以promise也可以是正常类型
}
/**
* auth安全字段类型
*/
export interface AxiosBasicCredentials {
username: string;
password: string;
}
/**
* 取消请求的token类型
*/
export interface CancelToken {
promise: Promise<Cancel>;
/**
* reason的类型改变成一个Cancel的类型
*/
reason?: Cancel;
/**
* 如果Cancel(就是已经取消过)再次使用直接抛出异常
*/
throwIfRequested():void;
}
/**
* 取消方法的类型
*/
export interface Canceler {
(message?: string): void;
}
/**
* 取消的执行者方法类型
*/
export interface CancelExecutor {
(cancel: Canceler): void
}
/**
* CancelToken通过Source方法返回的类型
*/
export interface CancelTokenSource {
token: CancelToken;
cancel: Canceler;
}
/**
* CancelToken的一个类类型
*/
export interface CancelTokenStatic {
/**
* 这个类类型传入一个executor取消执行者方法,并返回一个CancelToken的实例
*/
new(executor: CancelExecutor): CancelToken;
/**
* source方法就是返回一个CancelTokenSource的类型
*/
source(): CancelTokenSource;
}
/**
* 取消的类型
*/
export interface Cancel {
message?: string;
}
/**
* cancel的类类型
*/
export interface CancelStatic {
// 构造函数
new(message?: string): Cancel;
}
// _app.tsx
import App, { AppInitialProps } from 'next/app';
import { AppPropsType } from 'next/dist/next-server/lib/utils';
class MyApp extends App<AppInitialProps & AppPropsType,{}> {
// ...
}
type AppInitialProps = {
pageProps: any;
}
export declare type AppPropsType<R extends NextRouter = NextRouter, P = {}> = AppInitialProps & {
Component: NextComponentType<NextPageContext, any, P>;
router: R;
};
(alias) type AppContextType<R extends NextRouter = NextRouter> = {
Component: NextComponentType<NextPageContext, {}, {}>;
AppTree: ComponentType<AppInitialProps & {
[name: string]: any;
}>;
ctx: NextPageContext;
router: R;
}
NextPageContext则是上下文的内容,不包括Component组件和router,但是内部包括了request、response等
export interface NextPageContext {
// next的错误对象
err?: Error & {
statusCode?: number;
} | null;
// next的请求对象
req?: IncomingMessage;
// next的响应对象
res?: ServerResponse;
// 整个路径,除了域名什么的
pathname: string;
// query对象
query: ParsedUrlQuery;
// 排除query的路径
asPath?: string;
AppTree: AppTreeType;
}
NextRouter是next对router路由器的类型的包装,相比之下区别不大,和上面的RouteComponentProps,就新增了一些next的东西,正常用不到
(alias) type WithRouterProps = {
router: NextRouter;
}
其它类型可以通过观察React全家桶逐渐了解,或者在项目实战中挖掘
暂时就这么多了,接下来有新的发现会持续更新......
如果还想了解更多其它的可以点击我的头像查找别的博客、还有一些对新手来说还算可以的干货
?
React进阶用法和hooks的个人使用见解:
1.lazy+Suspense懒加载的使用
2.hooks的useState、useEffect、自定义钩子的实际使用
3.useCallback+useMemo+memo性能优化
4.useReducer+useContext+createContext的使用、模拟redux合并reducer
5.useRef,useImperativeHandle和forwardRef的结合使用以及useLayoutEffect、useDebugValue的简单使用