Skip to content
Advertisement

Typescript typecast object so specific required keys are no longer optional in the type?

Say you have an object type:

JavaScript

However you want to change that type into the following, where you know name and color will exist.

JavaScript

Therefore, there is the function

JavaScript

What is the proper way to type the params of the function as well as the return type (ReturnTypeHere)? Written correctly, the below will either 1) throw error 2) console log the name. It will never console log undefined.

JavaScript

Advertisement

Answer

If you have an object type T and a union of its keys K that you’d like to have required, you can write RequireKeys<T, K> like this:

JavaScript

Here we are using the Required<T>, Pick<T, K>, and Omit<T, K> utility types. There are probable edge cases here, such as if T has a string index signature and string appears inside K, but to a first approximation it should work.

It’s also a little difficult to understand what RequiredKeys<Person, "name" | "color"> is from how it’s displayed in your IDE:

JavaScript

If you want the compiler to be a little more explicit, you can do something like the following to expand the type into its properties:

JavaScript

which results in

JavaScript

which is easier to see.

You then need to make throwIfUndefined() a generic function so the compiler can keep track of the relationship between the object and requiredKeys passed in:

JavaScript

And to test:

JavaScript

If you want the compiler to remember that the literal types "name" and "color" are members of requiredKeys then you need to do something like a const assertion (i.e., as const) to tell it so. Otherwise requiredKeys would just be string[] and you’d get weird/wrong results (we could guard against these but it would be possibly out of scope here).

And now, the compiler understands that name and color are defined, whereas address is still optional:

JavaScript

Playground link to code

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement