DEV Community

Cover image for Typescript Partial<T>, where have you been my whole life?

Typescript Partial<T>, where have you been my whole life?

Nick Raphael on November 25, 2019

Oh boy, how did I not know about Partial until now? This is something all Typescripters need to know. I'll use the example based on the official ...
Collapse
 
emptyother profile image
emptyother •

I normally use Partial<T> interface when making class constructors.

class MyClass {
    myProp = 0; // Default values are applied first.
    constructor(cfg: Partial<MyClass> = {}) {
        extend(this, cfg); // Method that shallow-copies properties from cfg to this, overwriting any defaults.
    }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cookavich profile image
Paul Cook •

I do the same except with Object.assign with partials like so:

export class User {
    id: number;
    name: string;
    profile = new Profile();

    constructor(options?: Partial<User>) {
        Object.assign(this, options);
    }
}
Enter fullscreen mode Exit fullscreen mode

Works really nicely for creating and updating data.

onChangeUser(event: FormChangeEvent<UserForm>): void {
    this.user = new UpsertUser({
        ...this.user,
        ...event.value,
        profile: new Profile({
            ...this.user.profile,
            ...event.value.profile
        })
    });
}
Enter fullscreen mode Exit fullscreen mode

Rather than having a web of Object.assign everywhere you actually see and work with the shape of your data.

Collapse
 
daniel15 profile image
Daniel Lo Nigro •

Your extend method just looks like Object.assign :)

Collapse
 
emptyother profile image
emptyother • • Edited

Completely forgot that one exists. Symptom of working too much with an old IE11-supported javascript framework. :P

Thread Thread
 
nombrekeff profile image
Keff • • Edited

Nice, I didn't know about Partial, nice find, will be useful!

Yup it could be used, but take into account that Object.assign doesn't merge nested objects.

let objA = { b: { name: 'Train' } };
let objB = { b: { description: 'A vehicle that does not like to go uphill :)' } };

let merged = Object.assign(objA, objB);
> { b: { description: "A vehicle that does not like to go uphill :)" } }


Collapse
 
nickraphael profile image
Nick Raphael •

Interesting pattern. I may have to play with it. Thanks!

Collapse
 
nickytonline profile image
Nick Taylor • • Edited

Yeah Partial<T> is great. Another good one is Readonly<T>. It's a neat way to make things read-only, from a TS perspective even if under the hood (read JS), things are not truly read-only.

Readonly<T> example screenshot

Here's a TypeScript Playground example for those interested.

For reference, here's the full list of built-in Utilitiy Types. Lots of great stuff in there.

Looking forward to your next post!

Collapse
 
mgenteluci profile image
Matheus Genteluci •

It's also interesting to use the Omit<> type, which in most cases is actually a better fit because you can actually say which attibutes are not gonna be present.

Collapse
 
nickraphael profile image
Nick Raphael •

Shoutout to Fiona Tran for bringing Partial to my attention.

Collapse
 
thereverandnd profile image
The Reverand • • Edited

This a much faster way to type Pick<T,any> :) thanks!

Collapse
 
codermikky profile image
Sai Deep Konduri • • Edited

This partial pattern is completely awesome.. thanks @nick

Collapse
 
nick profile image
Nick •

Watch out...

Collapse
 
messified profile image
Jesse Reese •

Partial’s are tight!

Collapse
 
omerxx profile image
Omer Hamerman •

INCREDIBLE!
Thank you for that!!

Collapse
 
ogaston profile image
Omar Gaston Chalas •

wow, I didn't know about partial either, thanks for sharing

Collapse
 
hemalr profile image
Hemal •

Excellent! Just getting into Typescript and little tips like this are immensely helpful.

Thank you 👍

Collapse
 
zackdotcomputer profile image
Zack Sheppard •

This is great - also the first I'm learning about it!

Collapse
 
danielg212 profile image
Danielg212 •

why not simply use optional parameters ?

interface Todo {
    title?: string;
    description?: string;
 }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
scitronboy profile image
Benjamin Ashbaugh •

Just because something should be optional in a parameter for example doesn't mean it should be optional everywhere, as would happen if you set it optional in the interface