TypeScript Function Overloads and this Types (Error TS2769 and TS2684)
November 6, 2026
Welcome to episode 44 of TypeScript from Zero, a series for complete beginners (no JavaScript needed). Welcome back to TypeScript from zero! Two more features of functions. Overloads: one function with several ways to call it, and a different result for each. And the this type: telling tsc what this means inside a function. A new file called overloads.ts in the tasks project. Every code block below is the exact code and output from the video, ready to copy.
- All episodes are in the TypeScript from Zero playlist.
- Versions used: Node.js 26.13.0, npm 11.20.0, TypeScript 7.0.2.
Setup
We start in the terminal and open the project in VS Code:
cd tasks
touch src/overloads.ts
code .1. Overloads
Parse can take one text and give one number, or take a list of texts and give a list of numbers. We write the two allowed signatures first, without a body. Then the real function, with a body, that handles both. Outside, only the first two signatures are visible. So parse of a text gives a number, and we can add one. And parse of a list gives a list of numbers, so we can ask for its length.
src/overloads.ts:
function parse(input: string): number;
function parse(input: string[]): number[];
function parse(input: string | string[]): number | number[] {
return Array.isArray(input) ? input.map(Number) : Number(input);
}
const one = parse("5");
const many = parse(["1", "2"]);
console.log(one + 1, many.length);$ node src/overloads.ts
6 22. No match
A call that fits no signature is an error. Parse of forty two: no overload matches this call. TS2769. Notice that the implementation signature does not count. Callers only see the overloads.
src/overloads.ts:
function parse(input: string): number;
function parse(input: string[]): number[];
function parse(input: string | string[]): number | number[] {
return Array.isArray(input) ? input.map(Number) : Number(input);
}
const one = parse("5");
const many = parse(["1", "2"]);
console.log(one + 1, many.length);
parse(42);$ npx tsc --noEmit
src/overloads.ts:9:7 - error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'number' is not assignable to parameter of type 'string[]'.
9 parse(42);
~~
src/overloads.ts:2:10 - The last overload is declared here.
2 function parse(input: string[]): number[];
~~~~~
Found 1 error in src/overloads.ts:93. Fix
We delete the line, and tsc is quiet.
src/overloads.ts:
function parse(input: string): number;
function parse(input: string[]): number[];
function parse(input: string | string[]): number | number[] {
return Array.isArray(input) ? input.map(Number) : Number(input);
}
const one = parse("5");
const many = parse(["1", "2"]);
console.log(one + 1, many.length);$ npx tsc --noEmit4. this
In a method, this is the object that the method was called on. A counter has a count and a method inc. We can write this as a fake first parameter, with a type. It is only for tsc, and it is removed from the output. We call c dot inc, and the count is one.
src/overloads.ts:
function parse(input: string): number;
function parse(input: string[]): number[];
function parse(input: string | string[]): number | number[] {
return Array.isArray(input) ? input.map(Number) : Number(input);
}
const one = parse("5");
const many = parse(["1", "2"]);
console.log(one + 1, many.length);
type Counter = { count: number; inc(this: Counter): void };
const c: Counter = {
count: 0,
inc() {
this.count += 1;
},
};
c.inc();
console.log(c.count);$ node src/overloads.ts
6 2
15. Lost this
Now we take the method out of the object, and call it alone. This is lost: there is no object any more. Node crashes with: cannot read properties of undefined, reading count. And tsc had warned us: the this context of type void is not assignable to the method's this of type counter. TS2684.
src/overloads.ts:
function parse(input: string): number;
function parse(input: string[]): number[];
function parse(input: string | string[]): number | number[] {
return Array.isArray(input) ? input.map(Number) : Number(input);
}
const one = parse("5");
const many = parse(["1", "2"]);
console.log(one + 1, many.length);
type Counter = { count: number; inc(this: Counter): void };
const c: Counter = {
count: 0,
inc() {
this.count += 1;
},
};
c.inc();
console.log(c.count);
const loose = c.inc;
loose();$ node src/overloads.ts
6 2
1
file:///home/mah/tasks/src/overloads.ts:13
this.count += 1;
^
TypeError: Cannot read properties of undefined (reading 'count')
at inc (file:///home/mah/tasks/src/overloads.ts:13:5)
at file:///home/mah/tasks/src/overloads.ts:19:1
at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
at async node:internal/modules/esm/loader:650:26
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:105:5)
Node.js v26.13.0$ npx tsc --noEmit
src/overloads.ts:19:1 - error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Counter'.
19 loose();
~~~~~~~
Found 1 error in src/overloads.ts:196. Fix
We delete those two lines, and tsc is quiet again.
src/overloads.ts:
function parse(input: string): number;
function parse(input: string[]): number[];
function parse(input: string | string[]): number | number[] {
return Array.isArray(input) ? input.map(Number) : Number(input);
}
const one = parse("5");
const many = parse(["1", "2"]);
console.log(one + 1, many.length);
type Counter = { count: number; inc(this: Counter): void };
const c: Counter = {
count: 0,
inc() {
this.count += 1;
},
};
c.inc();
console.log(c.count);$ npx tsc --noEmitRecap
Today: overloads, with the signatures first and the implementation last, the no match error, the this parameter, and what happens when a method loses its object. Next episode: declaration files.