Partial, a Built-in generic type in TypeScript

JavaScript has types. But, those types are not strictly enforced. We have to use type guards in our code. There are three types of type guards.

To check if the type of a variable is a number, we use:

let sum = 0;
if (typeof count === 'number') {
  sum += count;
}

To check if a key exists on an object, we use:

if ('drive' in vehicle) {
  vehicle.drive();
}

To check if an object is an instance of a class, we use:

if (car instanceof Car) {
  car.drive();
}

A lot has changed with TypeScript. Now, the compiler understands types much better and let us know these things when we write code. However, there are times when TypeScript can be annoying. Consider this code:

interface LoanApplication {
  applicant: ApplicantInfo;
  amount: number;
  creditInfo: CreditInfo;
  references: Reference[];
}

const loanApplication: LoanApplication = {};
loanApplication.applicant = getApplicantInfo();
loanApplication.amount = amount;
loanApplication.creditInfo = getCreditInfo();
loanApplication.references = getReferences();

The above code just won't work. This is because we cannot instantiate loanApplication as an empty object. The compiler requires all the keys in LoanApplication to be provided at the time of instantiation.

interface LoanApplication {
  applicant?: ApplicantInfo;
  amount?: number;
  creditInfo?: CreditInfo;
  references?: Reference[];
}

If we define the LoanApplication interface with all keys optional, then the above code will work. But we don't want to change the interface definition. Fortunately, TypeScript has a way around this. It has a built-in utility type called Partial that is a generic type. It will convert all required keys as optional while we are using it.

const loanApplication: Partial<LoanApplication> = {};
loanApplication.applicant = getApplicantInfo();
loanApplication.amount = amount;
loanApplication.creditInfo = getCreditInfo();
loanApplication.references = getReferences();
const completedLoanApplication = loanApplication as LoanApplication;

The above code works. We just use Partial<> generic type while declaring the variable. After we complete filling up all the keys, we cast the Partial variable back to the interface type. With just two lines of additional code, we have good type safety in our code.

For more interesting syntaxes in TypeScript, check out my other blog post.