Useful custom TypeScript utility types
1// Make specific properties optional
2type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
3
4// Make specific properties required
5type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
6
7// Deep partial - makes all nested properties optional
8type DeepPartial<T> = {
9 [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
10};
11
12// Get function return type
13type Awaited<T> = T extends Promise<infer U> ? U : T;
14
15// Make type mutable (remove readonly)
16type Mutable<T> = {
17 -readonly [P in keyof T]: T[P];
18};
19
20// Extract keys by value type
21type KeysOfType<T, U> = {
22 [K in keyof T]: T[K] extends U ? K : never;
23}[keyof T];
24
25// Usage examples
26interface User {
27 id: string;
28 name: string;
29 email: string;
30 age?: number;
31}
32
33// Make 'email' optional
34type UserWithOptionalEmail = PartialBy<User, 'email'>;
35
36// Make 'age' required
37type UserWithRequiredAge = RequiredBy<User, 'age'>;
38
39// Get only string keys
40type StringKeys = KeysOfType<User, string>; // 'id' | 'name' | 'email'
41
42// Deep partial for nested objects
43interface Config {
44 api: {
45 url: string;
46 timeout: number;
47 retry: {
48 attempts: number;
49 delay: number;
50 };
51 };
52}
53
54type PartialConfig = DeepPartial<Config>;
55// All properties at all levels are now optionalOrganize your team's code snippets with Snippetly. Share knowledge and boost productivity across your organization.