How to Pick Some Properties of a TypeScript Type and Make Them Optional?

Learn how to construct a new type from an existing one with specific properties as optional

The Partial utility type in TypeScript does not allow specific set of property keys to be selected. Instead it makes all properties of the specified type optional. In this article, we will see how we can pick a set of specific properties and make them optional.

For all the examples in this article, let's assume we have the following object:

interface Foo {
    bar: string;
    baz: number;
    qux: boolean;
}

Pick Specified Properties and Make Them Optional

If you want to pick a few properties from an existing type and make them optional, then we can create, for example a PartialPick utility type for that purpose, like so:

type PartialPick<T, K extends keyof T> = {
    [P in K]?: T[P];
};

Following are some examples of using the PartialPick type we created:

// pick only 'bar' and 'qux' from `Foo` and make them optional
type Example = PartialPick<Foo, 'bar' | 'qux'>;

const ex1: Example = { bar: 'xyz', qux: true }
const ex2: Example = { bar: 'xyz' }
const ex3: Example = { qux: true }
const ex4: Example = { }

// error: Object literal may only specify known properties...
const ex5: Example = { invalid: 'not-allowed' }
const ex6: Example = { baz: 123 }

Include All Properties and Make Some Optional

As opposed to only picking selective properties and making only them optional, there may be situations where you may want to include all properties of a type with some of them as optional. We can do that with a custom utility type, for example CopyWithPartial, like so:

type CopyWithPartial<T, K extends keyof T> = Omit<T, K> & Partial<T>;

Following are some examples of using the CopyWithPartial type we created:

// copy `Foo` but make 'bar' and 'qux' optional
type Example = CopyWithPartial<Foo, 'bar' | 'qux'>;

const ex1: Example = { bar: 'xyz', qux: true, baz: 123 }
const ex2: Example = { bar: 'xyz', baz: 123 }
const ex3: Example = { qux: true, baz: 123 }
const ex4: Example = { baz: 123 }

// error: Property 'baz' is missing in type...
const ex5: Example = { bar: 'xyz', qux: true }
const ex6: Example = { bar: 'xyz' }
const ex7: Example = { qux: true }
const ex8: Example = { }

Hope you found this post useful. It was published . Please show your love and support by sharing this post.