Introduction to the

When using React + typescript + ANTD, we often get confused about how to use the correct type definition. In this article, we will explain the common type definitions involved in this process one by one, along with some use cases. The purpose of this article is to keep a note for myself. I will not enumerate them here.

The react ts type definition is broken down

React internal component definitions

  • React.ReactText
    • string
    • number
  • React.ReactChild
    • ReactText
    • The React components
  • React.ReactNode
    • ReactChild
    • ReactFragment
    • ReactPortal
    • boolean
    • null
    • undefined
const elementOrPrimitive: React.ReactNode = 'string' || 0 || false || null || undefined || <div /> || <MyComponent />;
const Component = ({ children: React.ReactNode }) = >.Copy the code
  • React.CSSProperties

React CSS property, which represents a Style Object in a JSX file (usually used in CSS-in-JS)

const styles: React.CSSProperties = { flexDirection: 'row'.const element = <div style={styles} .
Copy the code
  • React.FunctionComponent<P={}>

FC<P={}>, stateless component (SFC), type definition of a function component, a generic interface that accepts a parameter, optionally passed, to define the type of props.

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

A generic class that takes two arguments, the first is a type definition for props and the second is a type definition for state (which can be omitted if a parent component passes a property method or defines state, but is not required if it does not, as is the case without TypeScript).

import React, { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom';
interface CountProps extends RouteComponentProps {// Can inherit from other interface types
	count: number;
	asyncAddCount: (count: number) = > void;
	asyncReduceCount: (count: number) = > void;
}
interface CountStateType{// Only defined when needed
}
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>)}}Copy the code
  • JSX.ElementorReact.ReactElement<P>

The JSX syntax type returned by return, as in render above.

const elementOnly: React.ReactElement = <div /> || <MyComponent />;
Copy the code
  • ComponentClass<P,S={}>

The class type, the generic interface, can be used in higher-order components when receiving a class or function.

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 > ); }}Copy the code
  • Context

The type of context is what it is, a generic interface.

// The type definition of the source code is as follows: we can see that we need to pass a type so that the parameter types are consistent
interface Context<T> {
	Provider: Provider<T>; Consumer: Consumer<T>; displayName? :string;
}
Copy the code
  • Dispatch<any>

A generic interface to define the type of dispatches, often used in dispatches generated by useReducer.

// Create an asynchronous action function that returns an asynchronous action object
const asyncAction = (dispatch: Dispatch<any>) = > {
  return {
    asyncAddaction() {
      console.log('Before executing addActions:' + Date.now());
      setTimeout(() = > {
        console.log('Execute addActions:' + Date.now());
        dispatch(addActions());
      }, 1000); }}}Copy the code
  • LazyExoticComponent

Lazy loaded types, generic interfaces, can accept various types of arguments, as the case may be, for example:

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'))}]Copy the code
  • RefForwardingComponent<T, P = {}>

ForwardRef, ref Forward type definition, generic interface, receive two parameters.

forwardRef(Editors) as RefForwardingComponent<any.any>;
// is the type of ref and props, respectively, and can be defined as any for simplicity
// The source types are defined as follows
 interface RefForwardingComponent<T, P = {}> {
	(props: PropsWithChildren<P>, ref: Ref<T>): ReactElement | null; propTypes? : WeakValidationMap<P>; / contextTypes? : ValidationMap<any>; defaultProps? : Partial<P>; displayName? :string;
 }
Copy the code
  • MutableRefObject<any>

A generic interface that accepts one parameter, which can be of any type, as the type definition for useRef.

const prctureRef: React.MutableRefObject<any> = useRef();
Copy the code
  • useState<any>

The useState of hooks is a generic function that passes a type to define the hooks.

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

UseRef is also a generic function that can be passed to a type if you want to be more precise. UseReducer is also a generic function.

Other:

interface IProps{
    name: React.ReactText; children? : React.ReactChild; header? : React.ReactNode; }Copy the code

React-router common type

  • RouteComponentProps

The most common type of routing the API definition, includes the history, location, match, staticContext type definition of the four routing API

import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
export default function Admin({ history, location, match }: RouteComponentProps) {
	return(<>This is the home page</>);
}
Copy the code

React internal event definitions

  • FormEvent

A React form form has the event type.

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

The react onChange event triggers the event type. This is a generic interface and uses the following:

<input 
	type="text" 
	value={count} 
	onChange={(e: ChangeEvent<HTMLInputElement>) => { setCount(e.currentTarget.value); //HTMLInputElement represents an HTML input node}} />Copy the code

Optional generic types :HTMLSelectElement, HTMLInputElement, HTMLDivElement, HTMLTextAreaElement and other HTML tag nodes of all types. There are various other event handling types, which can be viewed at @types/ React.

  • SyntheticEvent<T = Element, E = Event>

Generic interfaces, event wrappers, which are collections of native events, are combinations of native events.

Your event handler will pass an instance of SyntheticEvent, which is a cross-browser native event wrapper. (Official introduction)

<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>
Copy the code

As you can see from the above, the generic interface for composing events can be applied to any event.

  • Other event types are not completely exemplified

Sample code:

import React, { FC, ReactElement, MouseEvent  } from 'react'

type Props = {
    label: string.children: ReactElement, onClick? :(e: MouseEvent<HTMLButtonElement>) = > void
}

const FunctionComponent: FC<Props> = ({ label, children, onClick }: Props) = > {
    return (
        <div>
            <span>{label} :</span>
            <button type="button" onClick={onClick}>
                {children}
            </button>
        </div>)}export default FunctionComponent
Copy the code
  • React.ReactEventHandler<HTMLElement>

Common React Event Handler

const handleChange: React.ReactEventHandler<HTMLInputElement> = (ev) = >{... } <input onChange={handleChange} ... />Copy the code

Type definition of Antd

  • FormComponentProps

For use with the Form component

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;
Copy the code

The type of the form is WrappedFormUtils, which is normally defined when the form is assigned.

  • ColumnProps<any>

The type of each entry of the columns property of the table definition, with the any parameter indicating the type of table data, as shown in the following example:

interface ProductType {
  key:string;
  name:string;
  desc:string
}
const columns: ColumnProps<ProductType>[] = [
  {
    title: 'Trade Name'.dataIndex: 'name'
  },
  {
    title: 'Merchandise Details'.dataIndex: 'desc'}]Copy the code

Third, other

  • Promise<any>
interface IResponse<T> {
  message: string.result: T,
  success: boolean,}async function getResponse () :Promise<IResponse<number[] > >{
  return {
    message: 'Obtain success'.result: [1.2.3].success: true,
  }
}
getResponse()
  .then(response= > {
    console.log(response.result)
  })
Copy the code
  • axios
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
const server: AxiosInstance = axios.create();
server.interceptors.request.use((config: AxiosRequestConfig) = > {// Request interception
    return config;
});
server.interceptors.response.use((res: AxiosResponse) = > {
    if (res.status === 200) {
        res = res.data;
    }
    return res;
},(err:AxiosError) = >{});
Copy the code