Skip to main content

Typescript

Defined here is some best practice around Typescript that we all try to follow.

Type vs interface​

Agree standard?

Definitions and use​

Where possible component prop types should be defined in the same file as the components export. For more complicated component directory structures though (top level index.tsx with a components subfolder) you may have to create a types.tsx at the top level and store all types there to avoid cycle dependency errors.

Top level types folder​

Creating a top level types folder with files containing global type definitions can be useful - for example you could have one called cms.ts that contains type definitions for template ACF fields, custom post types etc. that can be imported and used globally e.g.

src/types/cms.ts
...

export interface CmsImageType {
alt: string;
caption: string;
date: string;
description: string;
height: number;
id: number;
mime_type: string;
title: string;
url: string;
width: number;
}


export interface CmsLinkType {
title: string;
url: string;
target: string;
}

export interface CmsIntegrationCategoryType {
id: number;
name: string;
slug: string;
}

export interface CmsIntegrationPostType {
ID: number;
featured_image: CmsFeaturedImageType;
permalink: string;
post_title: string;
integration_category: CmsIntegrationCategoryType[];
acf: {
content: {
dark_logo: CmsImageType;
light_logo: CmsImageType;
description: string;
external_link: CmsLinkType;
heading: string;
};
};
}

...

Think reusability​

When defining types try to avoid defining objects on objects unless for single use cases - if the object is defined as another type it can be imported and reused elsewhere - particulary useful for array types, as the type from the parent component can be exported and reused on a child component for the mapped children e.g.

...

// This
export interface CmsIntegrationCategoryType {
id: number;
name: string;
slug: string;
}

export interface CmsIntegrationPostType {
ID: number;
featured_image: CmsFeaturedImageType;
permalink: string;
post_title: string;
integration_category: CmsIntegrationCategoryType[];
acf: {
content: {
dark_logo: CmsImageType;
light_logo: CmsImageType;
description: string;
external_link: CmsLinkType;
heading: string;
};
};
}

// Instead of this
export interface CmsIntegrationPostType {
ID: number;
featured_image: CmsFeaturedImageType;
permalink: string;
post_title: string;
integration_category: {
id: number;
name: string;
slug: string;
}[];
acf: {
content: {
dark_logo: CmsImageType;
light_logo: CmsImageType;
description: string;
external_link: CmsLinkType;
heading: string;
};
};
}

...

Smart mindset​

When defining component props think if the type you are defining may already exist on another component/in the main types folder.