This TypeScript error occurs when you try to call a function that might be null or undefined without checking first. Enable strict null checks in tsconfig.json and use optional chaining (?.), null checks, or type assertions to safely invoke functions.
When TypeScript's `strictNullChecks` compiler option is enabled, variables are not automatically assumed to allow `null` or `undefined` values. If you declare a variable as possibly null (like `function | null`), TypeScript won't let you invoke it without first verifying it's not null. This error prevents a common runtime bug: trying to call a function that doesn't exist. It's a type safety feature that catches mistakes at compile time rather than failing at runtime with "Cannot read property of null." The error typically appears when: - A function parameter might be undefined - An API returns data that could be null - You're accessing a property that might not exist - You're working with optional callback functions
First, ensure strict null checks are enabled in your TypeScript configuration:
{
"compilerOptions": {
"strictNullChecks": true
}
}Or use the strict flag which enables all strict type-checking options:
{
"compilerOptions": {
"strict": true
}
}This is the recommended configuration for all TypeScript projects.
The cleanest modern solution is the optional chaining operator. It safely calls the function only if it's not null or undefined:
// ❌ Error: Object is possibly 'null'
const result = myFunction();
// ✅ Safe: Uses optional chaining
const result = myFunction?.();
// Example with object methods
type Employee = { doWork?: () => void };
const employee: Employee = {};
// ✅ Safely calls doWork if it exists
employee.doWork?.();If the function is null, the expression short-circuits and returns undefined instead of throwing an error.
Check that the function exists before calling it:
const callback: (() => void) | null = getCallback();
// ✅ Check before invoking
if (callback) {
callback();
}
// ✅ Alternative with !== null
if (callback !== null) {
callback();
}
// ✅ Alternative with typeof check
if (typeof callback === 'function') {
callback();
}This approach is explicit and clear about the intent.
The && operator short-circuits if the left side is falsy:
const callback: (() => void) | null = getCallback();
// ✅ Calls callback only if it's not null/undefined
callback && callback();
// ✅ With arrow function
const result = callback && callback();This is more concise but slightly less readable than an explicit if statement.
If you're certain a value is not null, you can use the ! assertion:
const callback: (() => void) | null = getCallback();
// ⚠️ Assert that callback is not null
callback!();WARNING: This bypasses TypeScript's type safety. Only use when you're absolutely certain the value is not null at runtime. If you're wrong, you'll get a runtime error.
Better approach: Fix the type or add a proper check instead of using !.
If you're receiving a callback function parameter, type it properly:
// ❌ Bad: Allowing null in the parameter
function process(callback: (() => void) | null) {
callback?.();
}
// ✅ Better: Make callback required
function process(callback: () => void) {
callback();
}
// ✅ Or use optional syntax if it's actually optional
function process(callback?: () => void) {
callback?.();
}The difference: callback: Function | null vs callback?: Function (optional parameter).
### Optional vs Nullable Parameters
There's an important distinction:
// ❌ Parameter is required but value can be null
function a(fn: (() => void) | null) { }
// ✅ Parameter is optional, if provided can't be null
function b(fn?: () => void) { }
// ✅ Parameter is required and can't be null
function c(fn: () => void) { }Use optional parameters (fn?: ...) when the function doesn't need to be provided. Use | null only when you specifically need to pass null as a value.
### strictNullChecks vs Non-Strict Mode
Without strictNullChecks, TypeScript ignores null/undefined in types, allowing these calls without errors. However, this defeats the purpose of using TypeScript—you lose compile-time safety.
Always enable strictNullChecks. Every major TypeScript project uses it.
### React useCallback Example
A common pattern in React:
import { useCallback } from 'react';
interface Props {
onSuccess?: (data: string) => void;
}
function MyComponent({ onSuccess }: Props) {
const handleClick = useCallback(() => {
// ❌ Error: onSuccess is possibly undefined
onSuccess('done');
// ✅ Safe with optional chaining
onSuccess?.('done');
// ✅ Or check first
if (onSuccess) {
onSuccess('done');
}
}, [onSuccess]);
return <button onClick={handleClick}>Click me</button>;
}### Filtering null from arrays
When working with arrays of possibly-null functions:
const callbacks: ((() => void) | null)[] = [fn1, null, fn2];
// ✅ Use filter to remove nulls
callbacks.filter((cb) => cb !== null).forEach((cb) => cb());
// ✅ Or use optional chaining on each
callbacks.forEach((cb) => cb?.());Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript