What are Template Literal Types?
After TypeScript 4.1 came out, we now can use the “Template Literal Type”. There are so many awesome features in it. In this article, I will highlight some features, but it is very recommended to read the official docs.

Template Literal Type?
It is making a new type from the string literal type of TypeScript.
- Basic
type Justin = 'justin';type JustinLee = '${Justin} Lee';
We now can combine string and type to make a new type.
- Union Type
type Banana = 'banana';
type Toppings = 'chocalate' | 'strawberries' | 'blueberries' | 'syrup';//type BananaToppings = 'banana chocolate' | 'banana strawberries' | 'banana blueberries' | 'banana syrup';
type BananaToppings = `${Banana} ${Toppings}`;
You can simply link types, you can extend your type to various ways.
- Union Types
type VerticalAlignment = "top" | "middle" | "bottom";
type HorizontalAlignment = "left" | "center" | "right";// type Alignments =
// | "top-left" | "top-center" | "top-right"
// | "middle-left" | "middle-center" | "middle-right"
// | "bottom-left" | "bottom-center" | "bottom-right"type Alignments = `${VerticalAlignment}-${HorizontalAlignment}`;
- Key Remapping in Mapped Types
type Options = {
[K in "isLoading" | "hasElements" | "isActive"]?: boolean;
};// same as
// type Options = {
// isLoading?: boolean,
// hasElements?: boolean,
// isActive?: boolean
// };
- Capitalize<type>
type Get<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};interface User {
name: string;
age: number;
location: string;
}type CapitalizedUser = Get<User>;
// type CapitalizedUser = {
// getName: () => string;
// getAge: () => number;
// getLocation: () => string;
//}
- Interfacing type
//Simple literal typestype InOrOut<T> = T extends `fade${infer R}` ? R : never;//type I = "In"
type I = InOrOut<"fadeIn">;
//type O = "Out"
type O = InOrOut<"fadeOut">;
//Split literal with '.'type Split<S extends string> =
S extends `${infer T}.${infer U}` ? [T, ...Split<U>] : [S];// type S = ["foo", "bar", "baz"];
type S = Split<"foo.bar.baz">;
- ValueOf (it’s not from 4.1 but just to keep in mind)
interface Foo {
foo: {
bar: {
baz: string;
}
}
}//type A = { bar: { baz: string} };
type A = ValueOf<Foo, ['foo']>;//type B = { baz : string };
type B = ValueOf<Foo, ['foo', 'bar']>;//type C = string;
type C = ValueOf<Foo, ['foo', 'bar', 'baz']>;
Ex1) Make JSON parser with TypeScript
// type Json = { key1: ['value1', null]; key2: 'value2' };
type Json = ParseJson<'{ "key1": ["value1", null], "key2": "value2" }'>;
As you can see you can just insert your JSON to ParseJson type.
Ex2) Make snake_case type to camelCase type
type CamelizeString<T extends PropertyKey> =
T extends string ? string extends T ? string :
T extends `${infer F}_${infer R}` ? `${F}${Capitalize<CamelizeString<R>>}` : T : T;
type Camelize<T> = { [K in keyof T as CamelizeString<K>]: T[K] }
type CamelizeExample = Camelize<Example>;
/* type CamelizeExample = {
firstName: string;
lastName: string;
homeTown: string;
} */
const e: Camelize<Example> = {
firstName: 'string',
lastName: 'string',
homeTown: 'string'
}

Awesome, Right?
References
- https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html
- https://github.com/ghoullier/awesome-template-literal-types
- https://stackoverflow.com/questions/57807009/typescript-generic-to-turn-underscore-object-to-camel-case?fbclid=IwAR0vGsulpbvLCFVhXpaaMfhOR7DqwUbuQPFOaiB9nfHn_Sk9sCZXPAHOoXE
- https://twitter.com/buildsghost/status/1301976526603206657