Designing Your Types 11 exercises

Constrain Keys in a StrictOmit Type Helper

Here's the starting point of the StrictOmit type and the ShouldFail example that we need to fix:

type StrictOmit<T, K> = Omit<T, K>
type ShouldFail = StrictOmit<
{ a: string },
// @ts-expect-error // red squiggly line under @ts-expect-error

Our goal is to update `Stri

Loading solution


00:00 Okay, let's do it. We want to constrain this K here and we want to constrain it to be something that like, okay, we could do like this for instance. We could say K extends B. Interesting. Now because K extends B, or let's say K extends A for instance, actually this makes more sense.

00:16 So what we're doing here is if we hover over strict omit, we've got T and we've got K extends A, and then we're passing in A and it's going to error because it's not constrained to A here. It's not satisfying the constraint A. But actually we want to say, okay, whatever the keys

00:32 of T are, we want to basically say K is got to be constrained to those keys. So instead of A, instead of like doing this sort of crappy version, we can say key of T. So type parameters can rely on other type parameters in order to basically get there, sort of do some logic. So now what

00:52 we're saying here is we've got strict omit and we're passing in A. And if we do some autocomplete here, we end up with A as the only option. If we add C number, for instance, then we get A or C here. And just like omit, we can actually pass in both of these too. So we can say C or A here.

01:10 And if I add B string, then finally we're going to be able to pass in B too. So we can say C or A or B, or of course, just B or a combination of them. So this is pretty cool. The fact that you can constrain type parameters to other versions of, to other type parameters that already exist

01:28 and get a kind of dynamic situation going on. And this strict omit type helper is super useful if you want omits to behave more like PIC.