DEV Community

Cover image for 13 Typescript Utility: A Cheat Sheet for Developer
Rahul Sharma
Rahul Sharma

Posted on • Updated on

13 Typescript Utility: A Cheat Sheet for Developer

Typescript is very powerful in terms of type checking, but sometimes it gets tedious when some types are subsets of other types and you need to define type checking for them.

Let's take an example, you have 2 response types:

UserProfileResponse
interface UserProfileResponse {
  id: number;
  name: string;
  email: string;
  phone: string;
  avatar: string;
}
Enter fullscreen mode Exit fullscreen mode
LoginResponse
interface LoginResponse {
  id: number;
  name: string;
}
Enter fullscreen mode Exit fullscreen mode

Instead of defining types of same context LoginResponse and UserProfileResponse, we can define type for UserProfileResponse and pick some properties for LoginResponse.

type LoginResponse = Pick<UserProfileResponse, "id" | "name">;
Enter fullscreen mode Exit fullscreen mode

Let's understand some utility functions that can help you to write better code.

Uppercase

Constructs a type with all properties of Type set to uppercase.
type Role = "admin" | "user" | "guest";

// Bad practice šŸ’©
type UppercaseRole = "ADMIN" | "USER" | "GUEST";

// Good practice āœ…
type UppercaseRole = Uppercase<Role>; // "ADMIN" | "USER" | "GUEST"
Enter fullscreen mode Exit fullscreen mode

Lowercase

Constructs a type with all properties of Type set to lowercase. Opposite of Uppercase.
type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice šŸ’©
type LowercaseRole = "admin" | "user" | "guest";

// Good practice āœ…
type LowercaseRole = Lowercase<Role>; // "admin" | "user" | "guest"
Enter fullscreen mode Exit fullscreen mode

Capitalize

Constructs a type with all properties of Type set to capitalize.
type Role = "admin" | "user" | "guest";

// Bad practice šŸ’©
type CapitalizeRole = "Admin" | "User" | "Guest";

// Good practice āœ…
type CapitalizeRole = Capitalize<Role>; // "Admin" | "User" | "Guest"
Enter fullscreen mode Exit fullscreen mode

Uncapitalize

Constructs a type with all properties of Type set to uncapitalize. Opposite of Capitalize.
type Role = "Admin" | "User" | "Guest";

// Bad practice šŸ’©
type UncapitalizeRole = "admin" | "user" | "guest";

// Good practice āœ…
type UncapitalizeRole = Uncapitalize<Role>; // "admin" | "user" | "guest"
Enter fullscreen mode Exit fullscreen mode

Partial

Constructs a type with all properties of Type set to optional.
interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice šŸ’©
interface PartialUser {
  name?: string;
  age?: number;
  password?: string;
}

// Good practice āœ…
type PartialUser = Partial<User>;
Enter fullscreen mode Exit fullscreen mode

Required
Constructs a type consisting of all properties of Type set to required. Opposite of Partial.
interface User {
  name?: string;
  age?: number;
  password?: string;
}

// Bad practice šŸ’©
interface RequiredUser {
  name: string;
  age: number;
  password: string;
}

// Good practice āœ…
type RequiredUser = Required<User>;
Enter fullscreen mode Exit fullscreen mode

Readonly

Constructs a type consisting of all properties of Type set to readonly.
interface User {
  role: string;
}

// Bad practice šŸ’©
const user: User = { role: "ADMIN" };
user.role = "USER";

// Good practice āœ…
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = { role: "ADMIN" };
user.role = "USER"; // Error: Cannot assign to 'role' because it is a read-only property.
Enter fullscreen mode Exit fullscreen mode

Record

Constructs a type with a set of properties K of type T. Each property K is mapped to the type T.
interface Address {
  street: string;
  pin: number;
}

interface Addresses {
  home: Address;
  office: Address;
}

// Alternative āœ…
type AddressesRecord = Record<"home" | "office", Address>;
Enter fullscreen mode Exit fullscreen mode

Pick

Pick only the properties of Type whose keys are in the union type keys.
interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice šŸ’©
interface UserPartial {
  name: string;
  age: number;
}

// Good practice āœ…
type UserPartial = Pick<User, "name" | "age">;
Enter fullscreen mode Exit fullscreen mode

Omit

Omit only the properties of Type whose keys are in the union type keys.
interface User {
  name: string;
  age: number;
  password: string;
}

// Bad practice šŸ’©
interface UserPartial {
  name: string;
  age: number;
}

// Good practice āœ…
type UserPartial = Omit<User, "password">;
Enter fullscreen mode Exit fullscreen mode

Exclude

Constructs a type with all properties of Type except for those whose keys are in the union type Excluded.
type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice šŸ’©
type NonAdminRole = "USER" | "GUEST";

// Good practice āœ…
type NonAdmin = Exclude<Role, "ADMIN">; // "USER" | "GUEST"
Enter fullscreen mode Exit fullscreen mode

Extract

Constructs a type with all properties of Type whose keys are in the union type Extract.
type Role = "ADMIN" | "USER" | "GUEST";

// Bad practice šŸ’©
type AdminRole = "ADMIN";

// Good practice āœ…
type Admin = Extract<Role, "ADMIN">; // "ADMIN"
Enter fullscreen mode Exit fullscreen mode

NonNullable

Constructs a type with all properties of Type set to non-nullable.
type Role = "ADMIN" | "USER" | null;

// Bad practice šŸ’©
type NonNullableRole = "ADMIN" | "USER";

// Good practice āœ…
type NonNullableRole = NonNullable<Role>; // "ADMIN" | "USER"
Enter fullscreen mode Exit fullscreen mode

Must Read If you haven't
How to cancel Javascript API request with AbortController
28 Javascript Array Methods: A Cheat Sheet for Developer
How to solve Express.js REST API routing problem with decorators?
3 steps to create state management library with React Hooks and Context API

More content at Dev.to.
Catch me on Github, Twitter, LinkedIn, Medium, and Stackblitz.

Discussion (11)

Collapse
thethirdrace profile image
TheThirdRace

In my experience, the developers that partially or don't type at all will make a lot of mistakes along the way. Only the top 10% will still get it right... and I'm extremely generous with that percentage...

Correct typings force developers to think about how their data is structured, it helps them understand exactly how to manipulate and use that data correctly.

Correct typings add a lot of readability to your code and makes maintenance a lot easier. Both those things should trump pretty much anything else in priority. You can get away with a lot less elegant solution as long as the code is readable and easy to maintain.

Correct typings mostly eliminate runtime crashes, which I would argue are the absolute worst kind of bugs.

These things:

  • increase your customer confidence in your company, which leads to more sales
  • reduce the downtimes due to crashes, which leads to less expanses and more sales
  • reduce the debug time for developers, which leads to less expanses on maintenance for the company
  • increase the mental well being of developers, which in the end:

    • increase productivity
    • attracts more talent to your company
    • gets your product on the market faster
    • give you time to add more and great feature to your product
    • etc.

All this translate to less expanses and more sales.

I would never suggest go without typings as a professional.

Collapse
ayyash profile image
Ayyash

some of these if you never know about, its better :) but uppercase and lowercase? that's... interesting, I can see a good scenario for their use that involves directly mapping enums from database, though I still vouch for explicitness

thethirdrace profile image
TheThirdRace • Edited on

@dirkecker
I fully agree with the first part of your reply.

Java and C# developers tend to be especially "bad" at Javascript because they simply replicate their OOP model to a language that isn't OOP at all. This over-complicates a lot of code and bring a lot of frustrations to those that are from a Javascript background.

From your perspective, I can understand why you'd say typings are not needed.

While not very explicit, that's why I used "Correct typings" in my previous reply. A bunch of class with getter/setter is NOT what I was referring to...

The flaw in your argument is you're taking pretty much what NOT to do with typings and use it to discredit the whole idea of typings. You can use pretty much use anything the wrong way and do very bad things with them, doesn't mean these things should not be used the way they were intended...

Correct typings are like condoms. You don't absolutely NEED them, but you'd be pretty stupid not to use them... You can take all the precautions you want, but you can't control what others bring to the table šŸ˜…

thethirdrace profile image
TheThirdRace

I know it's a controversial opinion, but personally I think that if you're very good, you don't actually need typings or tests.

Typings and tests will slow you down on delivering your code. There's nothing to argue here:

Which is faster?

  1. Spend time on something
  2. Don't spend time at all

But you're not doing these for you, or at least not for the current you.

Typings and tests will make future you much faster to put yourself back in context and pickup where you left up. Both are an incredible time saver for future you.

And as soon as you add another developer or a team to the mix, typings and tests will make things much smoother for everyone.

Tests are the 1st par of the equation. They will show the intended use of the code.

Typings are the 2nd part of the equation. They will provide intellisense in your code editor and provide a safety net before wasting 20 minutes while your tests run.

Which is faster?

  1. Find the correct test > open it > analyze it > reproduce it > wait 20 minutes for the tests to complete >repeat if there's a failure
  2. Your code editor automatically give you all the information needed without having to think at all > get instant feedback if you're doing something wrong

Typings absolutely brings a lot to the table. They're not a replacement for tests either, both are needed to really give your team a boost.

You don't have to create over-complicated typings, you just need to describe the inputs and outputs of your function so that others can see at a glance how to use your function.

In any case, if this doesn't convince you, well I simply hope you will keep this in mind. Sometimes, it takes time for it to just "click" in place.

Have a good day!

Collapse
neo1380 profile image
Neo

Nice tips. Thanks for sharing.

sinanyilmaz profile image
Sinan Yilmaz

Well this is Not accurate. I think this just your opinion. I am comming from python and i love typescript. Without typing you can be more productive, yes, at least at the beginning. If a Projects grows, have fun maintaining it. If an api Changes, have fun Finding the bug in pure javascript. At last If you want top know best practices, look at big companies like microsoft, Google and why they use or do not use typescript