Typescript: Utility Types
Developers frequently claim that typescript requires them to write redundant code. The reasons can vary, but one of the most common is a failure to use utility types.
Types are analogous to utility functions in Javascript.
They are provided in typescript to make our lives easier. Let's take a look at them one at a time.
1. Partial
Partial<T>
allows you to create optional props with a single line of code. Without it, we'd need to duplicate the User type, which isn't ideal.
type User = {
name: string;
password: string;
}
// redundant codes
type OptionalUserProps = {
name?: string;
password?: string;
}
Below is an example of Partial
utility type.
type OptionalUsersProps = Partial<User>
Partial
takes type as an argument.
2. Required
Required<T>
is the inverse of Partial. It creates all the necessary props.
type Fish {
name: string;
food?: string[];
origin?: string;
}
// all the props are required.
type RequiredFish = Required<Fish>
Required
also takes type as an argument.
3. Readonly
In JavaScript, readonly
functions similarly to const. You cannot reassign a type once it has been marked as readonly
.
type Currency = {
America: "USD";
India: "INR";
France: "Euro";
}
type ReadOnlyCurrency = Readonly<Currency>;
4. NonNullable
NonNullable<T>
filters your type and removes null and undefined from the union of types.
// gender will have male and female type.
type Gender = NonNullable<"male" | "female" | null | undefined>;
5. Exclude
Exclude<T, K>
lets you remove type from the union types.
type Languages = "Java" | "JavaScript" | "TypeScript";
// Excluding Java from union type.
type MyFavLang = Exclude<Languages, "Java">;
// passing union type.
type TypeScriptOnly = Exclude<Languages, "Java" | "JavaScript">
It takes two arguments. The first is type, while the second is a union of props.
6. Extract
Extract<T, K>
is the inverse of Exclude
. It will generate union types based on the specified union type.
type Languages = "Java" | "JavaScript" | "TypeScript";
// Extract TypeScript and JavaScript from Languages.
type MyFavLang = Extract<Languages, "TypeScript" | "JavaScript">;
7. Pick
Pick<T, K>
picks props from type. It will give you a new type.
type Car {
engine: Engine;
wheels: Wheels;
color: "red" | "white" | "black";
speed: number;
}
// selecting engine and wheels only.
type CarService = Pick<Car, "engine" | "wheels">
8. Omit
Omit<T, K>
removes props from types.
type NewUser = {
name: string;
username: string;
password: number;
confirmPassword: number;
}
// password and confirmPassword will be removed
type User = Omit<NewUser, "password", "confirmPassword">
9. ReturnType
ReturnType<T>
gives return type of function.
// Type T can be string or number
type T = ReturnType<() => string | number>
10. Record
Record<T, K>
creates an object type.
Instead of doing this:
type SpaceShip = {
[k :string]: number;
}
You can do this:
type SpaceShip = Record<string, number>
const spaceship: SpaceShip = {
name: "StarShip",
color: "Red",
speed: "High"
}
// You can pass union type as key as well.
type Num = Record<string | number, number>
const numbers :Num = {
first: 1,
2: 2,
three: 3
}
Record also accepts union type as key that is not supported by interface and type.
As we can see, utility types help in avoiding redundancy in the codebase. It also enables maintaining a single source of truth.
That's it for today. I hope you enjoyed this blog. Stay tuned for upcoming blogs on the typescript.