Type interpolation and iterating through properties in TypeScript
Template Literal Types
- You can concat and interpolate types together like strings
type World = "world";
type Greeting = `hello ${World}`;
Documentation — Template Literal Types
Mapped Types
- You can iterate through properties of a type as if the code is being run.
type OptionsFlags<Type> = {
[Property in keyof Type]: boolean;
};
// Converts all values of a property to boolean
- You can even remap properties. Together with Template Literal Types, we can concat strings to each property of an object:
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
interface Person {
name: string;
age: number;
location: string;
}
type LazyPerson = Getters<Person>;
type LazyPerson = {
getName: () => string;
getAge: () => number;
getLocation: () => string;
}
Together with Conditional Types
Mapped types work well with other features in this type manipulation section, for example here is a mapped type using a conditional type which returns either a true or false depending on whether an object has the property pii set to the literal true:
type ExtractPII<Type> = {
[Property in keyof Type]: Type[Property] extends { pii: true } ? true : false;
};
type DBFields = {
id: { format: "incrementing" };
name: { type: string; pii: true };
};
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
Extracting All Methods from a Class
Then, we can do magic like this. This allows us to extract all methods from a class:
type PickMatching<T, V> =
{ [K in keyof T as T[K] extends V ? K : never]: T[K] }
type ExtractMethods<T> = PickMatching<T, Function>;
Basically, we are iterating through all properties of an object, and checking if the values match with V. If so, we return the value, otherwise return never for the value of the key, which is equivalent to omitting the type. The value is set as the value of the original object.
References:
How to create a type that extract all methods from a class in typescript?
This post is licensed under CC BY 4.0 by the author.