DEV Community

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

Posted on

1 1

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (1)

Collapse
 
kristiyanvelkov profile image
Kristiyan Velkov

Take your TypeScript skills to new heights with "Mastering TypeScript Core Utility Types":

📖 Buy on Leanpub
📖 Buy on Amazon

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs