DEV Community

Cover image for TypeScript Utility Types ~ Partial
Francesco Di Donato
Francesco Di Donato

Posted on

TypeScript Utility Types ~ Partial

I remember that time I understood the concept of the High-Order Function. Until then I had limited myself to using the methods forEach, map, filter, find, etc. Then, one day, I no longer remember how or why, I found myself looking inside them - a bit like a curious person grappling with analog clock gears. I turned them over and over, peeling off and refitting pieces until their inner workings became clear.

In this post I propose to apply a similar approach on TypeScript's utility types.


First it is necessary to understand how to refer to one of the properties in an object - keyof.

interface Hero {
    hp: number;
    sword: boolean;
    shield: boolean;
};

const hero: Hero = {
    hp: 42,
    sword: true,
    shield: false,
};

type HeroItem = keyof typeof hero; // "hp" | "sword" | "shield"
Enter fullscreen mode Exit fullscreen mode

Note: if the hero was defined via a class, there would be no need for typeof.

class Hero { ... }
type heroItem = keyof Hero;

Now, we want to allow the hero to be able to upgrade.

interface Hero {
    hp: number;
    sword: boolean;
    shield: boolean;
    upgrade: (items: Partial<Hero>) => void;
};

const hero: Hero = {
    hp: 42,
    sword: true,
    shield: false,
    upgrade(items) {
        Object.assign(this, items);
    }
};

hero.upgrade({ shield: true });
Enter fullscreen mode Exit fullscreen mode

Thanks to Partial<Hero>, the items parameter will make all the properties of the passed Hero conditional.

Once you know how to read it, the functioning of Partial is easy to grasp:

How it works?

  • Take a type (T) on which to operate
  • The result is an object (= { ... })
  • Each key should be dynamically assigned, hence the use of square brackets.
  • Each key is optional, thus the ?
  • The value must have the correct type; in the "key-side" we define a P (could be any letter or word) and use it to extrapolate the type from the subject type (T[P])
type myPartial = { [P in keyof T]?: T[P] }
Enter fullscreen mode Exit fullscreen mode

typescript/lib/lib.es5.d.ts

Feel free to linger at it until all the various bits and pieces are clear to you.

I don't implement Array.prototype.map for each new project - I get smart and use built-in. Use Partial.

References

Top comments (0)