preface

TypeScript + React type security is a three-piece package: Component, Redux, and Service typing.

Component typed

First install the React type dependency:

NPM i-d@types/react@types/react@types /react-domCopy the code

The base type

Generic components

React.ComponentType<P> = React.ComponentClass<P> | React.FunctionComponent<P>

Only component types (except HTML tag strings) can create a JSX.Element. For example:

Const C = () => <></>; const thisIsJSX = <C />; Const D = () => [<></>]; const throwError = <D />;Copy the code

So when we want to pass a component with props, we need to define:

    interface Props {
        /** Custom rendering component */
        Cp: React.ComponentType<any>;
    }
Copy the code

In the component that receives this property:

    props => {
        const { Cp } = props;
        return <Cp />;
    }
Copy the code

Functional component generics

FunctionComponent or React.StatelessComponent , abbreviated as react.fc or react.sfc. React.StatelessComponent and React.SFC are marked “not recommended” after React Hooks appear. ,> ,>

The corresponding return value must be jsx.Element, for example:

Const ThisIsFC = () => <></>; function ThisIsFCToo() { return <></>; } // Const ThisNotFC = () => [<></>]; function ThisIsNotFCNeither() { return [<></>]; }Copy the code

Class component generics

React.ponentclass ; react.ponentclass ,> ,>

    const C: React.ComponentClass = xxxxx;
    const jsx = <C />;
Copy the code

The generic element

The corresponding React.ElementType

, the equivalent React.ReactType has been marked “not recommended”.

JSX.Element = React.ElementType<any>

Component typing

Props typed

Taking a functional component as an example, define:

    type Props = xxxxxxx;
    const ThisIsFC: React.FC<Props> = props => <></>;
Copy the code

Props can be divided into the following subsets:

  • OwnProps, that is, create JSX<ThisIsFC ... />Attributes passed directly
  • StatePropsProperties obtained by connecting to the Redux Store
  • DispatchPropsIs also a property obtained by connecting to redux
  • RoutePropsThat is, properties passed via the React-router-dom Route

So:

    Props = OwnProps & RouteProps & StateProps & DispatchProps;
Copy the code

defineOwnPropsRoutePropsType:

    interface OwnProps {
        /** name */
        name: string;
    }
    
    import { RouteComponentProps } from 'react-router-dom';
    type RouteProps = RouteComponentProps<{ id: string }>;
Copy the code

In this way, we can use:

const ThisIsFC = props => { { const { id } = props.match.params; // cosnt STR: string = id; Const num: number = id; } { const { name } = props; // cosnt STR: string = id; Const num: number = id; } return <></>; }Copy the code

Type inference StateProps & DispatchProps

StateProps & DispatchProps cannot be written, because they can be inferred from the map* function.

Inference StateProps:

type StateProps = ReturnType<typeof mapStateToProps>; // TODO: Redux type function mapStateToProps(state: IRootState) {return {user: state.xxx.xxx}; }Copy the code

Inference DispatchProps:

import { bindActionCreators, Dispatch } from 'redux'; // TODO: Redux typed import actions from '.. /redux/actions'; type DispatchProps = ReturnType<typeof mapDispatchToProps>; function mapDispatchToProps(dispatch: Dispatch) { return { actions: bindActionCreators(actions, dispatch) }; }Copy the code

In this way, we can use:

    const ThisIsFC = props => {
        props.user;
        props.actions.doSomething;
        return <></>;
    }
Copy the code

Export components

import { connect } from 'react-redux';

export default connect<StateProps, DispatchProps, OwnProps>(
  mapStateToProps,
  mapDispatchToProps
)(ThisIsFC);
Copy the code

The same applies to class components, except that they have an extra State type set.

The advanced

Define generic components

function ThisIsGenericFC<P extends string | number>(props: Props<P>) {}
class ThisIsGenericComponent<P extends string | number> extends React.Component<Props<P>, State> {}

const jsxFC = <ThisIsGenericFC<string> />;
const jsxComponent = <ThisIsGenericComponent<number> />;
Copy the code

trailer

The next section is “Redux typing.”