How not to name your Types

May 28, 23

Naming conventions, also known as code nomenclature or coding conventions, are important in software development for several reasons: Readability, Maintainability, Code Reusability, Consistency, Documentations, and Scalability. Here we shall discuss some naming conventions I follow and recommend so that the next time you are writing new types it’s easier for you to name them.

How not to name your Types - cover

Casing πŸ” 

We’ve have been following some variant of casing in our javascript code since forever, like camelCase for variable names, etc. a similar convention has to be followed in typescript type naming so as to be able to differentiate between a javascript names (run time) and types (compile time) names as well as satisfy the code editor highlighting. It is generally recommended and followed across the industry to follow PascalCase naming for types and interfaces in typescript. Let’s understand with an example. In the example code below you can see there’s a slight conflict in the names for the type fruit vs the variable name.

// πŸ‘ŽπŸΌ Bad Naming
type fruit = 🍎 | 🍊 | πŸ₯­;

const fruit = πŸ₯­;

const eatFruit = (fruit: fruit) => {
// what is fruit?

// πŸ‘πŸΌ Better Naming
type Fruit = 🍎 | 🍊 | πŸ₯­;

const buyFruit = (fruit: Fruit) => {}

Descriptive πŸ—’οΈ

Type names should accurately describe the purpose and content of the type. For instance, in this example the type should clearly mention it refers to the react component types, and at the same time also define for which react component the type is for.

// πŸ‘ŽπŸΌ Bad Naming
// As there can be multiple react component in this file
interface Props {}

// πŸ‘ŽπŸΌ Bad Naming
// Just the name Table doesn't reflect it content
// appending Props clearly states that it is props
interface Table {}

// πŸ‘πŸΌ Better Naming
interface TableProps {}

const Table: React.FC<TableProps> = () => {}

Avoid I and T πŸ™…πŸ»β€β™‚οΈ

Avoid prefixes like I and T you might have seen some codebase writing their type names with I or T prefix, denoting that they are interfaces or types respectively, but actually if you think more deeply they don’t add any values at all, moreover it looks ugly to me personally. Also, think of a case when you change it from a type to an interface, would you be going to each instances and renaming it. I would suggest just avoid these prefixes.

// πŸ‘ŽπŸΌ Bad Naming
type TFruit = 🍎 | 🍊 | πŸ₯­;
interface ITableProps {}

// πŸ‘πŸΌ Better Naming
type Fruit = 🍎 | 🍊 | πŸ₯­;
interface TableProps {}

Generic Type Params πŸ₯‹

Just naming your generic type params as T or U can be very confusing, you might have seen people following conventions for naming their generic type params like T, U, V etc. it is as similar to just naming your function arguments as arg1 , arg2, arg3 - you can’t take out enough values out of it.

// πŸ‘ŽπŸΌ Bad Naming
interface DataState<T, U> {
data: T;
error: U;

// πŸ‘πŸΌ Better Naming
interface DataState<Data, Error> {
data: Data;
error: Error;

Don’t Pluralize 🎾

Many times, we declare types referring to a bunch of values, like fruits or something, but actually the type is not resembling multiple values, but a value out of them, let’s see from an example -

// πŸ‘ŽπŸΌ Bad Naming
type Fruits = 🍎 | 🍊 | πŸ₯­;

// But when you use it, you actually use only one value
const favFruit: Fruits = πŸ₯­;

// The problem here is the code understanding
// when you read the second line, it says favFruit is of type fruits
// which could mean multiple fruits.

// πŸ‘πŸΌ Better Naming
type Fruit = 🍎 | 🍊 | πŸ₯­;
const favFruit: Fruit = πŸ₯­;

type Fruits = Fruit[];
const allFruits: Fruits = [🍎, 🍊, πŸ₯­];

Until next time πŸ‘‹πŸ½