Skip to main content

React / TypeScript

Welcome to Posos' React/TypeScript Style Guide !

Typing of the function components

React components must be typed using the TypeScript type FunctionComponent provided by React.

Justification

Many will argue that the general consensus today is that the use of this type is discouraged. But here at Posos we think that this type bring consistent and exact types to our codebase. Thus, to us, the advantages we find in this type clearly exceed the drawbacks stated by their detractors.

The type FunctionComponent must be imported only via a named type import and only longnames must be used, i.e the use of shortnames FC and SFC is prohibitted.

If your component can accept a children property, you must use the type PropsWithChildren.

invalid
import type { ReactNode } from 'react';

type PososMessageProps = {
children?: ReactNode;
message: string;
};

// Declare a Function Component; return type is inferred.
const PososMessage = ({ children, message }: PososMessageProps) => (
<div>
<div>{message}</div>
{children}
</div>
);

// Annotate the return type so an error is raised if you accidentally return some other type.
const PososMessage = ({ childre, message }: PososMessageProps): JSX.Element => (
<div>
<div>{message}</div>
{children}
</div>
);
import React from 'react';

type PososMessageProps = {
children?: React.ReactNode;
message: string;
};

// Call type annotation via React namespace.
const PososMessage: React.FunctionComponent<PososMessageProps> = ({ children, message }) => (
<div>
<div>{message}</div>
{children}
</div>
);

// Call type annotation via its shortname
const PososMessage: React.FC<PososMessageProps> = ({ children, message }) => (
<div>
<div>{message}</div>
{children}
</div>
);
valid
import type { PropsWithChildren, FunctionComponent } from 'react'

type PososMessageProps = PropsWithChildren<{
message: string;
}>;

const PososMessage: FunctionComponent<PososMessageProps> = ({ children, message }) => (
<div>
<div>{message}</div>
{children}
</div>
);
import type { FunctionComponent } from 'react'

type PososInputProps = {
type: string;
};

const PososInput: FunctionComponent<PososInputProps> = ({ type }) => (
<input type={type} />
);

Typing of the forwardRef components

React forwardRef is a generic function that has type parameters for the type of the ref and the props:

forwardRef<RefType, PropsType>((props, ref) => {});

React forwardRef components must be typed using the forwardRef generic types provided by React.

invalid
import { forwardRef } from 'react';

type PososMessageProps = {
children: ReactNode;
message: string;
};

// Override the generic types
const PososMessage = forwardRef(({ children, message }: PososMessageProps, ref: HTMLDivElement): JSX.Element => (
<div ref={ref}>
<div>{message}</div>
{children}
</div>
));
import { forwardRef } from 'react';

type PososInputProps = {
type: string;
};

// Override the generic types
const PososInput = forwardRef(({ type }: PososInputProps, ref: HTMLInputElement): JSX.Element => (
<input ref={ref} type={type} />
));
valid
import type { PropsWithChildren } from 'react';
import { forwardRef } from 'react';

type PososMessageProps = PropsWithChildren<{
message: string;
}>;

// Override the generic types
const PososMessage = forwardRef<HTMLDivElement, PososMessageProps>(({ children, message }, ref) => (
<div ref={ref}>
<div>{message}</div>
{children}
</div>
));
import { forwardRef } from 'react';

type PososInputProps = {
type: string;
};

const PososInput = forwardRef<HTMLInputElement, PososInputProps>(({ type }, ref) => (
<input ref={ref} type={type} />
));