String Manipulation Types

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional TypeScript Masterclass Lessons

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11

String Manipulation Types

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Motivation

Its hard to create a conditional type for even simple things like UpperCase e.g.

export type UppercaseSimple<T> =
T extends 'a' ? 'A'
: T extends 'b' ? 'B'
// .... lots more
: T;

type a = UppercaseSimple<'a'>;
type b = UppercaseSimple<'b'>;

You would need this to be recursive, it quickly gets out of hand e.g.:

export type UppercaseRecursive<T> =
T extends `a${infer Rest}` ? `A${UppercaseRecursive<Rest>}`
: T extends `b${infer Rest}` ? `B${UppercaseRecursive<Rest>}`
// .... lots more
: T;

type abba = UppercaseRecursive<'abba'>;

This is why such things are built in to the compiler as intrinsic.

Intrinsic TypeScript Utilities

Uppercase

type abba = Uppercase<'abba'>; // 'ABBA'

Lowercase

type Loud = 'HELLO FAM';
type Quiet = Lowercase<Loud>; // 'hello fam'

Capitalize

type Hello = "fee fi fo fum";
type Better = Capitalize<Hello>; // 'Fee fi fo fum'

Uncapitalize

type Loud = 'HELLO FAM';
type UncomfortableGreeting = Uncapitalize<Loud>; // 'hELLO FAM'

Special Cases

Punctuation is Ignored

type Scream = Uppercase<'Hello!'>; // 'HELLO!'

Acutes are Preserved

type CV = Uppercase<'résumé'>; // "RÉSUMÉ"

Works With Greek

type GammaGamma = Uppercase<'ɣƔ'>; // 'ƔƔ'

Use Case

Most commonly used in Template Literal Types (a concept we covered in a previous lesson) e.g.:

type Getter<T extends string> = `get${Capitalize<T>}`;
type Setter<T extends string> = `set${Capitalize<T>}`;

type Name = 'name';

type GetName = Getter<Name>; // 'getName'
type SetName = Setter<Name>; // 'setName'
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

TypeScript has certain type utilities which are so powerful that they are encoded directly into the brain of the compiler. And in this tutorial we will look at one category of these related to string manipulation. So let's go consider creating a utility type function that takes a string literal as input and is designed to return its uppercase variant. Now this utility type that we've created will work for single character literals. We are only catering for A and B over here, but of course we can add more as well. And of course it'll uppercase to string literal A to its uppercase variant.

00:32

And the same is true for B as well. And if you wanted, we could even go one level beyond this and create recursive version as well that will first check if a particular string literal starts with A, and then in that case it'll uppercase the A and return the uppercase recursive variant of the rest of the string literal. It'll do the same for B and all of the other characters as well. And we can verify this by creating a string little that only contains characters A and B. And if you look at the result, you can see that it is indeed uppercase thanks to this recursive uppercase function.

01:05

Now if you want to build a type like this, as you would imagine every single time you would use this, the type strip compiler would have to go through all of the conditions to figure out what the output type should be. So to code the TypeScript compiler team, these types are built into the compiler for performance reasons. So instead of trying to create our own version, which I'm not going to lie, is probably not going to work that well, we are instead going to use the built-in type utility within TypeScript called uppercase, which does exactly the same thing which one apply to the lowercase ever, does exactly what we would expect and returns the uppercase abba.

01:37

Now, if you were to go to the definition of this particular type utility, you can see that it actually points to something called intrinsic. What this means is that there is actually no definition for this. This is something that is baked into the touch of compiler. Now, in addition to uppercase, there are a few other intrinsic string manipulation utilities as well. So let's take a look. Similar to uppercase, there is a lowercase type utility. So if you have a string, hello fam all capital, we pass it through lowercase, it returns the type, hello fam, all lowercase. There is also a type utility called capitalize,

02:09

which will capitalize the first character. So in this particular case, FI five four form the first character, which is F of fee, is going to get capitalized and everything else remains unchanged. And similar to capitalize is its inverse called uncapitalized. So if you were to pass in our loud, which has every character as capital, it is only going to turn the first one into lowercase. The edge becomes lowercase and everything else remains unchanged. Now if you are curious like me, these functions do not work on punctuations. So exclamation mark will remain unchanged

02:42

'cause there is no capital exclamation. But they do work on special characters. For example, the acute E in resume is going to be updated in the results. And similarly, if you had lowercase as well as capital Gamma, you can see that when we pass that through uppercase, both of them turn into capital Gamma. Now an obvious question that you're going to have is what would be the use case for something like this? And most commonly these are utilized by combining them with TypeScript template, literal types. As an example, we can create these utilities called getter and setter, which are designed to take a string literal

03:15

as an input and generate the name get and set respectively, followed by the capitalization of the past and string literal. So if we have a string called name, we can generate a getter for that called get name and a setter for that called set name. And we can verify that that is indeed the result by hovering over get name and then hovering over set name.

Professional TypeScript Masterclass

Professional TypeScript Masterclass

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11