How Intrinsic Type Manipulations work in TypeScript
📣 Sponsor
Did you know that TypeScript comes with a bunch of built in string manipulator types? That means we can easily transform a string
type into uppercase, lowercase, or capitalized versions of itself. When might this be useful? In lots of situations where you have a fixed set of string values, for example whenever you have a set of strings from an object using something like [keyof](https://fjolt.com/article/typescript-keyof)
.
To transform a string into a different version by defining a new type along with one of the type manipulators. For example, below we transform myType
into the capitalized version:
type myType = "hi there"
type capitalizedMyType = Capitalize<myType>
let myVar:capitalizedMyType = "Hi there";
In the above example, hi there
would throw an error - only Hi there
will work with a Capitalize
type. Similarly, we can uncapitalize a string using Uncapitalize
:
type myType = "HI THERE"
type uncapitalizedMyType = Uncapitalize<myType>
let myVar:uncapitalizedMyType = "hI THERE";
Above, only hI THERE
will work. Any other case will fail the check.
Uppercase and Lowercase Intrinsic Type Manipulation
Along with Capitalize
, we also have Uppercase
and Lowercase
. They both do exactly what you think they’d do - one changes all characters to uppercase, and the other to lowercase.
type myType = "this long sentence"
type bigMyType = Uppercase<myType>
let myVar:bigMyType = "THIS LONG SENTENCE"
Lowercase intrinsic type manipulation
Above we’ve created a type which is the uppercase version of myType
. Here is the same example, but in the other direction: making the lowercase version:
type myType = "THIS LONG SENTENCE"
type smallMyType = Lowercase<myType>
let myVar:smallMyType = "this long sentence"
Using with template literals
These types become very useful when working with template literals, where we can enforce a string literal to use a lowercase version - for example for an ID. Here is a version where we have a set number of strings, and we only want to use the lowercase version in the ID, as part of the versionId
type:
type versions = "DEV" | "PROD" | "STAGING"
type versionPrefix = "gold-" | "beta-" | "alpha-"
type versionId = `${versionPrefix}${Lowercase<versions>}`
let currentVersion:versionId = "gold-dev"
Above, we have two sets of union types, and we combine them into one versionId
. Here, we only accept lowercase letters, but version
is uppercase. We can transform it with Lowercase
, so gold-dev
is valid.
Using with keyof objects
In a similar way, we may receive an object from an API or elsewhere, which has odd or uneven casing. To normalise this, we can use intrinsic type manipulations. Below, I am using keyof
to get all the keys in myObject
, and making them all lowercase too.
type myObject = {
firstName: string,
Age: number,
Lastname: string
}
type keys = Lowercase<keyof myObject>
let getObjectKey:keys = "firstname"
keys
only has the following valid values: firstname | age | lastname
. In this example, using intrinsic string manipulation like this can be an easy way to create clean types when the data we have at our disposal has issues.
More Tips and Tricks for Typescript
- How Typescript Generic Types Work
- How to setup a new Project in Typescript
- TypeScript Array Type
- How keyof works in Typescript
- How the TypeScript Pick Type works
- Type Casting in TypeScript
- Typescript Tuples, and how they work
- How the typeof Operator works in TypeScript
- How the TypeScript Readonly Type Works
- How TypeScript Default Parameters Work