DEV Community

Cover image for How the TypeScript Required Type Works
Johnny Simpson
Johnny Simpson

Posted on • Originally published at fjolt.com

How the TypeScript Required Type Works

In TypeScript, we sometimes need to enforce that an object has required properties, even if the original type defined some of them as optional. For that, TypeScript has a utility type called Required. Let's look at how it works.

TypeScript Required Utility Type

By default, if we define a new type in TypeScript, all fields within that type are automatically required:

type User = {
    firstName: string,
    lastName: string
}

let firstUser:User = {
    firstName: "John"
}
Enter fullscreen mode Exit fullscreen mode

Above, firstUser is of type User, but it's missing lastName. As such, this code returns an error:

Property 'lastName' is missing in type '{ firstName: string; }' but required in type 'User'.
Enter fullscreen mode Exit fullscreen mode

If we expect a field to be optional, we can add a question mark to the end of it in our type definition. Below, we make lastName optional by writing lastName? instead:

type User = {
    firstName: string,
    lastName?: string
}

let firstUser:User = {
    firstName: "John"
}
Enter fullscreen mode Exit fullscreen mode

As such, this code does not throw an error - lastName is optional, so the fact that firstUser doesn't contain it is fine.

Forcing optional types to be required in TypeScript
Sometimes, we have a situation where most of the time, lastName is optional, but in some circumstances we require it to do something. In these cases, we can use the utility type Required. For example, if we want lastName to be required, even if it was originally defined as optional, we can write the following:

type User = {
    firstName: string,
    lastName?: string
}

let firstUser:User = {
    firstName: "John",
}

let secondUser:Required<User> = {
    firstName: "John"
}
Enter fullscreen mode Exit fullscreen mode

In this example, secondUser throws an error:

Property 'lastName' is missing in type '{ firstName: string; }' but required in type 'Required<User>'
Enter fullscreen mode Exit fullscreen mode

So since we've used Required, we have to add lastName to avoid the error:

type User = {
    firstName: string,
    lastName?: string
}

let secondUser:Required<User> = {
    firstName: "John",
    lastName: "Doe"
}
Enter fullscreen mode Exit fullscreen mode

This can give us more flexibility, while allowing us to enforce field requirements for certain functionality in an application. As with other utility types, Required is meant to work with an interface or object type, like the User type we defined above. As such, it doesn't work with variables. This doesn't matter much, though, since a variable cannot have an empty value anyway.

Top comments (7)

Collapse
 
fathidevs profile image
fathidevs

I heard about typescript couple of weeks ago while talking about Javascript (coz I'm learning it). From my basic js I can say it's similar in syntax, but what's the "type" keyword? Is it like "class"?

Collapse
 
smpnjn profile image
Johnny Simpson

I'll try to explain what TypeScript is briefly. All data has a type when we program something. For example, 5 is a number, "this-is-a-text" is a string, etc.

Javascript figures out the types by itself - so you never mention them in your code. That means if you write:

let x = 5;
Enter fullscreen mode Exit fullscreen mode

Javascript figures out it is a number. However, if we wrote:

let x = "5"
Enter fullscreen mode Exit fullscreen mode

Javascript will think it's a string, since we put 5 in quotation marks. This can mean in complicated applications, bugs can start to arise because we don't "enforce" types. For example "5" + "5" is 55, but 5 + 5 is 10.

Ideally, we would "enforce" "5" to be a number. TypeScript tries to fix this problem by adding types into Javascript, so they are all defined up front. Instead of the above, we write:

let x:number = 5;
Enter fullscreen mode Exit fullscreen mode

Now if "x" is not a number, we'll get an error. That way we can avoid bugs in our code.

Collapse
 
fathidevs profile image
fathidevs

thank you so much

Collapse
 
peerreynders profile image
peerreynders • Edited

but what's the "type" keyword? Is it like "class"?

No. A class is a template for creating objects.

A type alias is simply a name for a type. A type alias can describe an object type, union type, tuple type or array type.

Typescript is structurally typed. Languages like C# and Java are nominally typed which means that if two types have different names they are always treated as separate types. That is not the case with TypeScript.

If you have two types that go by a different names, TypeScript will treat them as equivalent if they have an identical shape. In the case of an object type the "shape" is derived from the key/value type pairs found on the object (regardless of order).

People more comfortable with class-oriented implementations tend to use interface and then extend them when implementing their classes. But plain objects can satisfy an interface, so there is no need to implement a class; a factory function for creating objects or even an object literal is good enough.

The one unique property of interfaces is that they merge so it's possible to declare an interface in bits and pieces and then objects have to implement all the merged requirements in order to satisfy the interface.

With type types can be intersected which basically combines the requirements of the intersected types (with a type union you only satisfy one of the types that comprise the union).

intersection versus union of types
Source

My personal opinion is that type aliases are more versatile as they can represent more than just object types. However when you are implementing classes and/or need declaration merging then interface can make sense.

While classes are types not all types are classes.

Collapse
 
fathidevs profile image
fathidevs

Thank you for the detailed explanation, appreciated so much

Collapse
 
curiousdev profile image
CuriousDev

It should be noted, that TypeScript basically is extended JavaScript. If you are still learning, it makes sense to stick a while to JS only.

Collapse
 
fathidevs profile image
fathidevs

thank you for the tip