Introduction
check version
New features
Pick vs Partial
Partial
and Pick
are mapped types. They are used to create a new type using part of original type.
e.g.
interface PartialTask {
id: string,
name: string,
contacts: any[]
}
interface Task extends PartialTask{
associatedJob: string,
submissionDate: string,
allocatedTime: number,
expectedCompletion: string,
assignee: string,
invoiceNumber: string,
invoiceDueDate: string,
comment: string,
taskAddress: string
...
... x 10
}
Here we have 2 versions of Task
type.
Partial
helps us create a clone type that mirrors a provided type(interface, class) with all properties:
type PartialTaskByPartial = Partial<Task>;
let taskObj : PartialTaskByPartial = null;
Here the new type PartialTaskByPartial
contains all properties of Task class.
Pick
is alternative to the above but gives us more powerful way. We can pick some of properties from original type to get a new type:
type PartialTaskByPick = Pick<Task, 'id' | 'associatedJob'>;
let partialTaskObj : PartialTaskByPick = null;
Here the new type PartialTaskByPick
only contains 2 properties: id, associatedJob
Demo 1
In practice, Pick
can help us create new objects with customized proproties from original types. e.g.
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
const copy = {} as Pick<T, K>;
keys.forEach(key => copy[key] = obj[key]);
return copy;
}
Then:
let originalObj = { "name": "someName", "age": 20, "date": "2015-01-03" };
let copy = pick(originalObj, "name", "age") as Test;
console.log(copy); // { name: "someName", "age": 20 }
Please note that here Pick
help us achieve this purpose via new empty object {} and add properties and copy value from original object into it. It has better performance than delete a property from original object.
Demo 2
Pick
is handy when you need to create a new type from an existing interface with only the specified keys, which is great but sometimes you need just the opposite. Like when you’re defining the return type for your API endpoint where you want to include everything except for one or two private fields.
So what you actually need is Omit
. It is not built-in and we will create for that:
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
this is how to use:
type PartialTaskByOmit = Omit<Employee, 'id' | 'associatedJob'>;
var partialTaskObj : PartialTaskByOmit ;
Here the new type PartialTaskByOmit
contains all properties of Task class except id, associatedJob
References
https://medium.com/@curtistatewilkinson/typescript-2-1-and-the-power-of-pick-ff433f1e6fb
http://ideasintosoftware.com/typescript-advanced-tricks/