M Logo
๐Ÿ“ TypeScript from Zero ยท Part 44 of 50

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.

Setup

We start in the terminal and open the project in VS Code:

bash
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:

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);
text
$ node src/overloads.ts
6 2

2. 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:

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);
text
$ 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:9

3. Fix

We delete the line, and tsc is quiet.

src/overloads.ts:

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);
bash
$ npx tsc --noEmit

4. 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:

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);
text
$ node src/overloads.ts
6 2
1

5. 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:

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();
text
$ 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
text
$ 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:19

6. Fix

We delete those two lines, and tsc is quiet again.

src/overloads.ts:

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);
bash
$ npx tsc --noEmit

Recap

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.

ยฉ 2026 All Rights Reserved By Mahmudul Alam