Question
I have the following TypeScript interface:
interface Employee {
id: number;
name: string;
salary: number;
}
I want to make the salary field nullable, similar to how nullable types work in C#. Is this possible in TypeScript, and if so, how should it be declared?
Short Answer
By the end of this page, you will understand how nullable types work in TypeScript, how to declare a property such as salary as null, and how this differs from making a property optional. You will also learn common patterns, mistakes, and practical examples for working with null, undefined, and union types in TypeScript.
Concept
In TypeScript, a type is made nullable by using a union type. A union type means a value can be one of several allowed types.
For example:
salary: number | null;
This means salary can hold either:
- a
number - or
null
That is the TypeScript way to represent nullable values.
This matters because real programs often deal with incomplete or missing data:
- a salary may not be known yet
- a database field may contain
NULL - an API may return
null - a form field may be intentionally cleared
TypeScript helps you model these cases safely.
A very important detail is the difference between these ideas:
- nullable: the property exists, but its value may be
null - optional: the property may be missing entirely
For example:
interface Employee {
salary: number | ;
}
Mental Model
Think of a property like a box with a label.
salary: numbermeans the box must contain a number.salary: number | nullmeans the box must exist, but it may contain either a number or an explicit "empty" value.salary?: numbermeans the box might not be there at all.
So:
null= the box exists, but it is intentionally emptyundefinedor optional = the box may be absent
This mental model helps when designing interfaces for APIs, database records, and user input.
Syntax and Examples
The basic syntax for a nullable property in TypeScript is:
interface Employee {
id: number;
name: string;
salary: number | null;
}
Example: nullable property
interface Employee {
id: number;
name: string;
salary: number | null;
}
const e1: Employee = {
id: 1,
name: "Ava",
salary: 50000
};
const e2: Employee = {
id: 2,
name: "Liam",
salary: null
};
Both objects are valid because salary can be either a number or null.
Step by Step Execution
Consider this example:
interface Employee {
id: number;
name: string;
salary: number | null;
}
const employee: Employee = {
id: 1,
name: "Mia",
salary: null
};
if (employee.salary !== null) {
console.log(employee.salary.toFixed(2));
} else {
console.log("No salary yet");
}
What happens step by step
- The interface says
salarycan be anumberornull. - The
employeeobject is created withsalary: null. - The
ifstatement checks whether is not .
Real World Use Cases
Nullable types are common in real applications.
Database records
A column such as salary, middleName, or deletedAt may be NULL in a database.
interface EmployeeRecord {
id: number;
salary: number | null;
}
API responses
An API may return null for fields that are known but currently empty.
interface UserProfile {
bio: string | null;
}
Forms
A user may clear an input, which may be represented as null before saving.
interface FormState {
age: number | null;
}
Scheduling and timestamps
Real Codebase Usage
In real projects, developers often use nullable types together with checks, defaults, and validation.
Guard clauses
A common pattern is to return early if a nullable value is missing.
function getAnnualSalary(employee: Employee): number | null {
if (employee.salary === null) {
return null;
}
return employee.salary * 12;
}
Default values
Sometimes developers convert null to a fallback value.
function getSalaryDisplay(employee: Employee): string {
return employee.salary ?? 0 + "";
}
A clearer version is:
function getSalaryDisplay(: ): {
(employee. ?? );
}
Common Mistakes
1. Confusing nullable with optional
This means nullable:
interface Employee {
salary: number | null;
}
This means optional:
interface Employee {
salary?: number;
}
These are not the same.
number | null=> property must exist, value may benullsalary?=> property may be missing
2. Forgetting to check for null before using the value
Broken code:
interface Employee {
salary: number | null;
}
function printSalary(employee: Employee) {
console.log(employee.salary.toFixed());
}
Comparisons
| Pattern | Meaning | Example | When to use |
|---|---|---|---|
salary: number | Must be a number | salary: 5000 | When the value is always required |
| `salary: number | null` | Must exist, but may be null | salary: null |
salary?: number | May be missing | no salary key | When the property is optional |
| `salary?: number | null` | May be missing or null | salary: null or omitted |
| `salary: number | undefined` |
Cheat Sheet
// Nullable property
interface Employee {
salary: number | null;
}
// Optional property
interface Employee {
salary?: number;
}
// Optional + nullable
interface Employee {
salary?: number | null;
}
Rules
- Use
| nullwhen a property may explicitly holdnull - Use
?when a property may be omitted - Use both if the property may be omitted or null
- Check nullable values before calling methods on them
- Prefer
strictNullChecksorstrict: true
Common checks
if (employee.salary !== null) {
console.log(employee.salary);
}
FAQ
How do I make a field nullable in TypeScript?
Use a union type:
salary: number | null;
Is salary?: number the same as salary: number | null?
No. salary?: number means the property can be missing. salary: number | null means the property must exist, but its value can be null.
Can a TypeScript property be both optional and nullable?
Yes:
salary?: number | null;
What is the TypeScript equivalent of C# int??
The closest equivalent is:
number | null
Should I use null or undefined in TypeScript?
Use whichever best matches your data model. null usually means intentionally empty. usually means missing or not assigned.
Mini Project
Description
Build a small employee formatter that safely handles nullable salary values. This demonstrates how to declare nullable properties in an interface and how to work with them without runtime errors.
Goal
Create a TypeScript program that prints employee salary information, showing a fallback message when salary is null.
Requirements
[ "Create an Employee interface with a nullable salary field", "Create at least two employee objects, one with a number salary and one with null", "Write a function that returns a readable salary message", "Avoid calling number methods unless salary is confirmed to be a number" ]
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular formControl Error with Material Autocomplete: Why It Happens and How to Fix It
Learn why Angular says it cannot bind to formControl and how to fix Reactive Forms setup with Angular Material Autocomplete.