How to Make a Single Property Optional in TypeScript ?
Last Updated :
15 May, 2024
TypeScript is a popular programming language that is a strict syntactical superset of JavaScript, adding optional static typing and class-based object-oriented programming to the language. One useful feature of TypeScript is the ability to specify optional properties in interfaces and classes, allowing you to define an object type that may or may not have certain properties.
Using Utility Type
This approach employs a utility type named MakeOptional
. The utility type uses TypeScript’s Omit
to exclude the specified property and introduce the ?
syntax to mark it as optional.
Syntax:
type MakePropertyOptional<T, K extends keyof T> = Omit<T, K> & { [P in K]?: T[P] };
Parameters:
T
: The original type.K
: The key of the property you want to make optional.
Note: It uses Omit<T, K>
to exclude the specified property and then introduces { [P in K]?: T[P] }
to add the property back as optional.
Example: here, we define a utility type MakeOptional
that takes a generic type T
and a property key K
. It utilizes TypeScript’s Omit
to exclude the specified property and introduce the ?
syntax to make it optional. The resulting ExampleWithOptionalAge
type is then used to create an object with the age
property being optional.
Javascript
type MakeOptional<T, K extends keyof T> =
Omit<T, K> & { [P in K]?: T[P] };
interface Example {
name: string;
age: number;
}
// Make 'age' property optional
type ExampleWithOptionalAge =
MakeOptional<Example, 'age'>;
// Example usage:
const optionalAgeExample:
ExampleWithOptionalAge = { name: 'John' };
console.log(optionalAgeExample);
Output:
{ "name": "John" }
Optional Property Inside an Interface:
In TypeScript, an interface is a way to define the structure of an object. When making a property optional inside an interface, you use the ?
modifier after the property name.
Example: Here,
the lastName
property is marked as optional by appending ?
after its name in the Person
interface. This allows objects of type Person
to either include or exclude the lastName
property. The person1
object doesn’t have a lastName
property, while the person2
object includes it. Attempting to create an object without the required properties (firstName
and age
in this case) will result in a compilation error.
Javascript
interface Person {
firstName: string;
lastName?: string;
age: number;
}
// Valid usage
const person1: Person = {
firstName: "John",
age: 25
};
// Valid usage with optional property
const person2: Person = {
firstName: "Alice",
lastName: "Johnson",
age: 30
};
// Error: Missing required property 'age'
const person3: Person = {
firstName: "Bob"
};
Output:
Property 'age' is missing in type '{ firstName: string; }' but required in type 'Person'.
Optional Property Inside a Class:
In TypeScript, a class is a blueprint for creating objects. When making a property optional inside a class, you declare the property with a ?
modifier in the class definition. Additionally, you may need to adjust the constructor to handle the optional property.
Example: Here, the lastName
property is marked as optional in the Person
class. When creating instances of the class, you can choose to provide or omit the lastName
property. The person1
instance is created without specifying the lastName
, while the person2
instance includes it.
Javascript
class Person {
firstName: string;
// Making lastName optional
lastName?: string;
age: number;
constructor(firstName: string,
age: number,
lastName?: string) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
}
// Creating instances
const person1 = new Person("John", 25);
const person2 = new Person("Alice", 30, "Johnson");
console.log(person1);
console.log(person2);
Output:
Person: {
"firstName": "John",
"lastName": undefined,
"age": 25
}
Person: {
"firstName": "Alice",
"lastName": "Johnson",
"age": 30
}
Using Object Spread Syntax
This approach leverages the object spread syntax to create a new object with the specified property marked as optional.
Syntax:
interface OriginalType {
// Define properties here
}
// Making a single property optional using object spread syntax
const newObject = { ...originalObject, propertyName?: value };
Parameters:
- originalObject: The original object.
- propertyName: The name of the property you want to make optional.
- value: Optional value for the property.
Example: Here’s how you can make a single property optional in TypeScript using object spread syntax:
JavaScript
interface Example {
name: string;
age: number;
}
// Original object
const originalExample: Example = { name: 'GFG', age: 22 };
// Make 'age' property optional using object spread syntax
const optionalAgeExample: Partial<Example> = { ...originalExample, age: undefined };
console.log(optionalAgeExample);
Output:
{
"name": "GFG",
"age": undefined
}
Using Conditional and Mapped Types
This approach introduces a utility type called OptionalProperty that makes a specified property optional. Unlike previous methods, it employs advanced TypeScript features for a streamlined solution.
Syntax:
type OptionalProperty<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
Parameters:
- T: The original type.
- K: The key of the property you want to make optional.
This utility type first removes the specified property from the type (Omit<T, K>) and then reintroduces it as optional using Partial<Pick<T, K>>.
Example: Here, we define a utility type OptionalProperty that takes a generic type T and a property key K. It utilizes TypeScript’s Omit and Partial to make the specified property optional. The resulting PersonWithOptionalLastName type is then used to create an object with the lastName property being optional.
JavaScript
type OptionalProperty<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
interface Person {
firstName: string;
lastName: string;
age: number;
}
// Make 'lastName' property optional
type PersonWithOptionalLastName = OptionalProperty<Person, 'lastName'>;
// Example usage:
const person1: PersonWithOptionalLastName = { firstName: 'John', age: 25 };
const person2: PersonWithOptionalLastName = { firstName: 'Alice', lastName: 'Johnson', age: 30 };
console.log(person1); // Output: { firstName: 'John', age: 25 }
console.log(person2); // Output: { firstName: 'Alice', lastName: 'Johnson', age: 30 }
Output:
{ firstName: 'John', age: 25 }
{ firstName: 'Alice', lastName: 'Johnson', age: 30 }
Share your thoughts in the comments
Please Login to comment...