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.
...
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.