Skip to content

Null Handling ​

In JavaScript and TypeScript, null and undefined are distinct values. null is an intentional absence of a value, while undefined represents a variable that has been declared but not assigned a value. JavaScript allows both null and undefined to be used interchangeably in some cases (e.g., loose equality comparisons), but TypeScript can enforce stricter handling with the strictNullChecks option, preventing unintended null or undefined assignments unless explicitly allowed.

C# does not have undefined; every variable must have a defined value. Value types (e.g., int, bool) cannot be null unless explicitly made nullable using ? (e.g., int? x = null;). Reference types (e.g., string, object) can be null by default. To improve null safety, C# includes nullable reference types (string? name = null;), allowing developers to indicate which variables can be null and leveraging compiler warnings to prevent unintended null dereferences.

Nullability ​

ts
let x: string | null;

function findUser(name: string, email?: string ) {
  if (!email?.trim()) {
    // Handle case when email is null or zero length
  }
}

let handle = email?.split("@")[0];

// Null forgiving operator
let handle = email!.split("@")[0];
csharp
string? x;

User[] FindUser(string name, string? email) {
  if (string.IsNullOrWhiteSpace(email)) {
    // Handle case when email is null or zero length
  }
}

var handle = email?.Split("@")[0];

// Null forgiving operator
var handle = email!.Split("@")[0];

Null Coalescing ​

ts
let handle = email?.split("@")[0] ?? userId;

handle ??= "unknown"
// πŸ‘†πŸ‘‡These are equivalent
if (handle === null) {
  handle === "unknown"
}
csharp
var handle = email?.Split("@")[0] ?? userId;

handle ??= "unknown"
// πŸ‘†πŸ‘‡These are equivalent
if (handle == null) {
  handle == "unknown"
}

In C#, we can also use pattern matching with null values like this:

csharp
class User {
  public int Id { get; set; }
  public string? FirstName { get; set; }
  public string? LastName { get; set; }
}

if (user is { FirstName: null, Id: > 10000 }) {
  // FirstName is null and ID is greater than 10000
}

Tim Deschryver has the best writeup on pattern matching

Nullability with Generics ​

ts
type List<T> = { }

// "Elements are string or null or undefined"
let list: List<string | null | undefined>;

let arr: Array<string | null | undefined>[];
csharp
// List<T> is a standard library collection type

// "Elements are string or null"
List<string?> list;

string?[] arr;