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"
}
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'.
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"
}
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"
}
In this example, secondUser throws an error:
Property 'lastName' is missing in type '{ firstName: string; }' but required in type 'Required<User>'
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"
}
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)
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"?
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:
Javascript figures out it is a number. However, if we wrote:
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:
Now if "x" is not a number, we'll get an error. That way we can avoid bugs in our code.
thank you so much
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 theinterface
.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).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 theninterface
can make sense.While classes are types not all types are classes.
Thank you for the detailed explanation, appreciated so much
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.
thank you for the tip