Common Errors

Below you find a list of common TypeScript errors along with the buggy code and its fixed version.

TS1016

error TS1016: A required parameter cannot follow an optional parameter.

Bad Code ❌

1
2
3
function createUser(firstName: string, lastName: string, middleName?: string, age: number) {
// ...
}

Fixed Code ✔️

The easiest way to fix the error is to make age optional as well:

1
2
3
function createUser(firstName: string, lastName: string, middleName?: string, age?: number) {
// ...
}

Alternatively, you can flip the order of middleName and age. Be aware that this breaks the contract (signature) of the function and is considered a “breaking change”:

1
2
3
function createUser(firstName: string, lastName: string, age: number, middleName?: string) {
// ...
}

You could also make middleName non-optional:

1
2
3
function createUser(firstName: string, lastName: string, middleName: string, age?: number) {
// ...
}

Yet another solution would be to assign a default value to middleName so it won’t be optional by default. This allows age to be optional then:

1
2
3
function createUser(firstName: string, lastName: string, middleName: string = '', age?: number) {
// ...
}

TS1029

error TS1029: ‘public’ modifier must precede ‘abstract’ modifier.

Bad Code ❌

1
2
3
abstract class Animal {
abstract public makeNoise(): string;
}

Fixed Code ✔️

They keywords public, private, and protected define the access to a class member. Access modifiers have to be defined first in TypeScript.

Solution 1:

1
2
3
abstract class Animal {
public abstract makeNoise(): string;
}

Solution 2:

The visibility is public by default, so you don’t have to explicitly declare it:

1
2
3
abstract class Animal {
abstract makeNoise(): string;
}

Video: https://youtu.be/62J_eQsK0e0?t=531


TS1036

error TS1036: Statements are not allowed in ambient contexts.

Bad Code ❌

1
2
3
4
5
import { APIClient } from "../../APIClient";

declare global {
client: APIClient;
}

Fixed Code ✔️

With declare global an ambient context is created. TypeScript does not allow statements in such ambient context declaration which is why we have to change the statement into a declaration:

1
2
3
declare global {
function client(): APIClient;
}

TS1055

error TS1055: Type ‘AxiosPromise‘ is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export const sendRequestWithCookie = async (
client: HttpClient,
config: AxiosRequestConfig,
engine: CRUDEngine
): AxiosPromise => {
const cookie: Cookie = await loadExistingCookie(engine);

if (!cookie.isExpired) {
config.headers = config.headers || {};
config.headers['Cookie'] = `zuid=${cookie.zuid}`;
config.withCredentials = true;
}

return client._sendRequest(config);
};

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export const sendRequestWithCookie = (
client: HttpClient,
config: AxiosRequestConfig,
engine: CRUDEngine
): AxiosPromise => {
return loadExistingCookie(engine).then((cookie: Cookie) => {
if (!cookie.isExpired) {
config.headers = config.headers || {};
config.headers['Cookie'] = `zuid=${cookie.zuid}`;
config.withCredentials = true;
}

return client._sendRequest(config);
});
};

TS1066

error TS1066: In ambient enum declarations member initializer must be constant expression.

Bad Code ❌

1
2
3
4
5
enum PreKeyAuth {
INVALID = 'Invalid',
UNKNOWN = 'Unknown',
VALID = 'Valid'
}

Fixed Code ✔️

1
type PreKeyAuth = 'Invalid' | 'Unknown' | 'Valid';

TS1070

TS1070: ‘private’ modifier cannot appear on a type member.

Bad Code ❌

1
2
3
interface Animal {
private name: string;
}

Fixed Code ✔️

Interfaces are structures that define the public contract. This prohibits you from using private modifiers. Only public and protected can be used. To solve the problem, the private keyword must be removed from the name property of the Animal interface:

1
2
3
interface Animal {
name: string;
}

Video: https://youtu.be/62J_eQsK0e0?t=165


TS1109

error TS1109: Expression expected.

Bad Code ❌

1
2
const name = ['Benny', '']
const lastName = name[1] || throw new Error('Missing last name');

Fixed Code ✔️

1
2
3
4
5
const name = ['Benny', ''];
const lastName = name[1];
if (!lastName) {
throw new Error('Missing last name');
}

TS1155

error TS1155: ‘const’ declarations must be initialized.

Bad Code ❌

1
const name: string;

Fixed Code ✔️

1
const name: string = 'Benny';

TS1192

error TS1192: Module ‘.../logdown‘ has no default export.

Bad Code ❌

1
2
3
4
5
declare class Logdown {
// ...
}

export = Logdown;

Fixed Code ✔️

1
2
3
4
5
declare class Logdown {
// ...
}

export default Logdown;

TS1202

error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using ‘import * as ns from “mod”‘, ‘import {a} from “mod”‘, ‘import d from “mod”‘, or another module format instead.

Bad Code ❌

1
import sinon = require('sinon');

Fixed Code ✔️

1
import * as sinon from 'sinon';

TS1208

error TS1208: ‘index.ts’ cannot be compiled under ‘–isolatedModules’ because it is considered a global script file. Add an import, export, or an empty ‘export {}’ statement to make it a module.

Bad Code ❌

tsconfig.json

1
2
3
4
5
{
"compilerOptions": {
"isolatedModules": true
}
}

index.ts

1
2
3
require(`dotenv-defaults`).config({
path: '.env',
});

Fixed Code ✔️

To solve the issue you can turn off isolatedModules in your tsconfig.json. If you want to keep going with isolated modules, then you have to add an import or export to your code:

index.ts

1
2
3
4
5
require(`dotenv-defaults`).config({
path: '.env',
});

export default {};

TS1218

error TS1218: Export assignment is not supported when ‘–module’ flag is ‘system’.

Bad Code ❌

1
2
3
4
5
class LRUCache {
// ...
}

export = LRUCache;

Fixed Code ✔️

1
2
3
export class LRUCache {
// ...
}

TS1243

error TS1243: ‘static’ modifier cannot be used with ‘abstract’ modifier.

Solution

Bad Code ❌

1
2
3
abstract class CustomNumber {
abstract static getNumber(): number;
}

Your abstract class cannot define an abstract static function. You have to keep it static:

Fixed Code ✔️

1
2
3
4
5
abstract class CustomNumber {
static getNumber(): number {
return 1337;
};
}

TS17009

TS17009: ‘super’ must be called before accessing ‘this’ in the constructor of a derived class.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
12
abstract class Animal {
abstract name: string;
}

class Dog extends Animal {
public name;

constructor(name: string) {
this.name = name;
super();
}
}

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
10
11
12
abstract class Animal {
abstract name: string;
}

class Dog extends Animal {
public name;

constructor(name: string) {
super();
this.name = name;
}
}

TS18004

error TS18004: No value exists in scope for the shorthand property ‘age’. Either declare one or provide an initializer.

Bad Code ❌

1
2
3
4
5
6
7
export function getPerson() {
return {
age,
fistName: 'Benny',
lastName: 'Neugebauer'
}
}

Fixed Code ✔️

1
2
3
4
5
6
7
8
export function getPerson() {
const age = 34;
return {
age,
fistName: 'Benny',
lastName: 'Neugebauer',
};
}

Alternative:

1
2
3
4
5
6
7
export function getPerson() {
return {
age: 34,
fistName: 'Benny',
lastName: 'Neugebauer',
};
}

TS2304

error TS2304: Cannot find name ‘world’.

Bad Code ❌

1
console.log(world.name);

Fixed Code ✔️

It can happen that TypeScript does not know about your global objects because those may be injected from an unknown runtime environment or third-party JavaScript library. The easiest way to let TypeScript know about this is to declare the ambience (ambient context):

1
2
3
4
5
declare var world: {
name: string;
};

console.log(world.name);

TS2304

error TS2304: Cannot find name ‘Promise’

Bad Code ❌

1
2
3
4
5
6
7
8
9
// ...

public load_prekey(prekey_id: number): Promise<Proteus.keys.PreKey> {
return new Promise((resolve) => {
resolve(42);
});
}

// ...

Fixed Code ✔️

Install es6-promise type definitions with the typings tool.

1
typings install dt~es6-promise --global --save

Adding the following line to the beginning of every file using definitions from es6-promise.

1
2
3
4
5
6
7
8
9
10
11
/// <reference path='es6-promise.d.ts' />

...

public load_prekey(prekey_id: number): Promise<Proteus.keys.PreKey> {
return new Promise((resolve) => {
resolve(42);
});
}

...

TS2304

error TS2304: Cannot find name ‘Promise’

Bad Code ❌

1
const UUID = require('uuidjs');

Fixed Code ✔️

1
npm install @types/node --save-dev

TS2305

error TS2305: Module ‘.../proteus‘ has no exported member ‘keys’.

Bad Code ❌

1
2
declare module keys {
}

Fixed Code ✔️

1
2
export module keys {
}

error TS2305: Module ‘.../proteus.keys‘ has no exported member ‘PreKey’.

Bad Code ❌

1
2
export module keys {
}

Fixed Code ✔️

1
2
3
4
export module keys {
class PreKey {
}
}

TS2306

error TS2306: File ‘../index.d.ts‘ is not a module.


TS2322

error TS2322: Type ‘Promise<{}>’ is not assignable to type ‘Promise

Bad Code ❌

1
2
3
4
function remove(prekey_id: number): Promise<void> {
this.removed_prekeys.push(prekey_id);
return Promise.resolve();
}

Fixed Code ✔️

1
2
3
4
function remove(prekey_id: number): Promise<void> {
this.removed_prekeys.push(prekey_id);
return Promise.resolve(undefined);
}

TS2339

error TS2339: Property ‘name‘ does not exist on type ‘Function‘.

Bad Code ❌

1
2
3
4
5
6
export class RecordNotFoundError extends Error {
constructor(public message: string) {
super(message);
this.name = this.constructor.name;
}
}

Fixed Code ✔️

1
2
3
4
5
6
export class RecordNotFoundError extends Error {
constructor(public message: string) {
super(message);
this.name = (<any>this).constructor.name;
}
}

TS2345

error TS2345: Argument of type ‘x‘ is not assignable to parameter of type ‘y‘.

1
2
3
4
5
6
error TS2345: Argument of type '(records: T[]) => void' is not assignable to parameter of type '(value: [{}, {}, {}, {}, > {}, {}, {}, {}, {}, {}]) => void | PromiseLike<void>'.
Types of parameters 'records' and 'value' are incompatible.
Type '[{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]' is not assignable to type 'T[]'.
Types of property 'pop' are incompatible.
Type '() => {}' is not assignable to type '() => T'.
Type '{}' is not assignable to type 'T'.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
readAll<T>(tableName: string): Promise<T[]> {
return this.resolvePath(tableName).then(directory => {
return new Promise<T[]>((resolve, reject) => {
fs.readdir(directory, (error, files) => {
if (error) {
reject(error);
} else {
const recordNames = files.map(file => path.basename(file, path.extname(file)));
const promises = recordNames.map(primaryKey => this.read(tableName, primaryKey));
Promise.all(promises).then((records: T[]) => resolve(records));
}
});
});
});
}

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
readAll<T>(tableName: string): Promise<T[]> {
return this.resolvePath(tableName).then(directory => {
return new Promise<T[]>((resolve, reject) => {
fs.readdir(directory, (error, files) => {
if (error) {
reject(error);
} else {
const recordNames = files.map(file => path.basename(file, path.extname(file)));
const promises: Array<Promise<T>> = recordNames.map(primaryKey => this.read(tableName, primaryKey));
Promise.all(promises).then((records: T[]) => resolve(records));
}
});
});
});
}

TS2348

error TS2348: Value of type ‘typeof BaseN’ is not callable. Did you mean to include ‘new’?

Bad Code ❌

1
2
3
import {BaseN} from 'js-combinatorics';

const iterator = BaseN([1, 2, 3], 2);

Fixed Code ✔️

1
2
3
import {BaseN} from 'js-combinatorics';

const iterator = new BaseN([1, 2, 3], 2);

TS2349

error TS2349: Cannot invoke an expression whose type lacks a call signature. Type ‘Promise‘ has no compatible call signatures.

Bad Code ❌

1
2
3
function bugged(param: Promise<Object>): void {
param().then(() => console.log('error TS2349'));
}

Fixed Code ✔️

1
2
3
function bugged(param: Promise<Object>): void {
param.then(() => console.log('error TS2349'));
}

TS2351

error TS2351: This expression is not constructable. Type ‘EMA‘ has no construct signatures.

Bad Code ❌

RSI.ts
1
2
3
4
5
6
7
export class RSI {
private readonly avgGain: MovingAverage;

constructor(private readonly interval: number, Indicator: EMA) {
this.avgGain = new Indicator(this.interval);
}
}
EMA.ts
1
export class EMA {}

Fixed Code ✔️

RSI.ts
1
2
3
4
5
6
7
export class RSI {
private readonly avgGain: MovingAverage;

constructor(private readonly interval: number, Indicator: typeof EMA) {
this.avgGain = new Indicator(this.interval);
}
}

TS2352

error TS2352: Conversion of type ‘’ to type ‘’ may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to ‘unknown’ first.

Bad Code ❌

1
2
3
4
5
6
7
8
9
interface MyInterface {
firstName: string;
age: number;
}

const myObject = {
name: 'Benny',
age: 34,
} as MyInterface;

Fixed Code ✔️

Stick to the properties of the interface (recommended):

1
2
3
4
5
6
7
8
9
interface MyInterface {
firstName: string;
age: number;
}

const myObject = {
firstName: 'Benny',
age: 34,
} as MyInterface;

Alternative: Convert your object to unknown first (not recommended):

1
2
3
4
5
6
7
8
9
interface MyInterface {
firstName: string;
age: number;
}

const myObject = {
name: 'Benny',
age: 34,
} as unknown as MyInterface;

TS2368

error TS2368: Type parameter name cannot be ‘number’.

Bad Code ❌

1
2
3
export interface SimpleNumberIndicator<number> {
update(price: T): T;
}

Fixed Code ✔️

The easiest way to fix the error is to make age optional as well:

1
2
3
export interface SimpleNumberIndicator<T = number> {
update(price: T): T;
}

TS2370

error TS2370: A rest parameter must be of an array type.

Bad Code ❌

1
2
3
4
5
export interface Indicator<R = Big> {
getResult(): R;

update(...args: R): void;
}

Fixed Code ✔️

A rest parameter allows a function to accept an indefinite number of parameters which why it is impossible to list all their types. That’s why TypeScript requires you to use the any typing for every rest parameter.

1
2
3
4
5
export interface Indicator<R = Big> {
getResult(): R;

update(...args: any): void;
}

TS2377

error TS2377: Constructors for derived classes must contain a ‘super’ call.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
abstract class Animal {
abstract name: string;
}

class Dog extends Animal {
public name;

constructor(name: string) {
this.name = name;
}
}

Fixed Code ✔️

Every constructor in a derived class has to call the super method to invoke the constructor of the base class. It has to be the very first call:

1
2
3
4
5
6
7
8
9
10
11
12
abstract class Animal {
abstract name: string;
}

class Dog extends Animal {
public name;

constructor(name: string) {
super();
this.name = name;
}
}

Video: https://youtu.be/62J_eQsK0e0?t=635


TS2391

error TS2391: Function implementation is missing or not immediately following the declaration.

Bad Code ❌

1
2
3
4
abstract class Animal {
abstract name: string;
makeNoise(): string;
}

Fixed Code ✔️

An abstract class is different from an interface. You have to use the abstract modifier if you want to define a contract in an abstract class. If there is no abstract modifier you will have to provide a implementation.

Solution 1:

To solve the problem, we can mark makeNoise with the abstract keyword. That will enforce derived classes to implement this method on their own:

1
2
3
4
abstract class Animal {
abstract name: string;
abstract makeNoise(): string;
}

Solution 2:

Another solution is to provide a base implementation for makeNoise:

1
2
3
4
5
6
abstract class Animal {
abstract name: string;
makeNoise(): string {
return 'Woof';
};
}

Video: https://youtu.be/62J_eQsK0e0?t=430


TS2394

error TS2394: This overload signature is not compatible with its implementation signature.

Bad Code ❌

The implementation does not match all signatures:

1
2
3
4
5
export function stringifyJSON(json: object): string;
export function stringifyJSON(json: string): string {
const sorted = parseJSON(json);
return JSON.stringify(sorted, null, 2);
}

Fixed Code ✔️

The implementation must match all signatures:

1
2
3
4
5
export function stringifyJSON(json: object): string;
export function stringifyJSON(json: string | object): string {
const sorted = typeof json === 'string' ? parseJSON(json) : json;
return JSON.stringify(sorted, null, 2);
}

TS2420

error TS2420: Class ‘Dog’ incorrectly implements interface ‘Animal’. Property ‘name’ is private in type ‘Dog’ but not in type ‘Animal’.

Bad Code ❌

1
2
3
4
5
6
7
8
interface Animal {
name: string;
}

class Dog implements Animal {
constructor(private name: string = 'Bobby') {
}
}

Fixed Code ✔️

The Animal interface defines a public name member. The name property in our Dog class must therefore also be public:

1
2
3
4
5
6
7
8
interface Animal {
name: string;
}

class Dog implements Animal {
constructor(public name: string = 'Bobby') {
}
}

Video: https://youtu.be/62J_eQsK0e0?t=242


TS2428

error TS2428: All declarations of ‘Strategy’ must have identical type parameters.

Bad Code ❌

Strategy.ts

1
2
3
4
5
6
7
8
9
10
11
enum TOPIC {
ON_LOGOUT = 'ON_LOGOUT',
}

export interface Strategy {
on(event: TOPIC.ON_LOGOUT, listener: (reason: string) => void): this;
}

export abstract class Strategy<SpecificConfig extends StrategyConfig> extends EventEmitter {
// ...
}

Fixed Code ✔️

Solution: The generic abstract class Strategy has a generic type parameter list in angle brackets (diamond notation). This generic type parameter list must also be added to the interface definition of Strategy.

Strategy.ts

1
2
3
4
5
6
7
8
9
10
11
enum TOPIC {
ON_LOGOUT = 'ON_LOGOUT',
}

export interface Strategy<SpecificConfig extends StrategyConfig> {
on(event: TOPIC.ON_LOGOUT, listener: (reason: string) => void): this;
}

export abstract class Strategy<SpecificConfig extends StrategyConfig> extends EventEmitter {
// ...
}

TS2445

error TS2445: Property ‘makeNoise’ is protected and only accessible within class ‘Dog’ and its subclasses.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
12
abstract class Animal {
protected abstract makeNoise(): string;
}

class Dog extends Animal {
protected makeNoise(): string {
return 'Woof!';
}
}

const laika = new Dog();
laika.makeNoise();

Fixed Code ✔️

The visibility of the makeNoise method is protected. We have to make it public if we want to call it directly from an instance of Dog:

1
2
3
4
5
6
7
8
9
10
11
12
abstract class Animal {
protected abstract makeNoise(): string;
}

class Dog extends Animal {
public makeNoise(): string {
return 'Woof!';
}
}

const laika = new Dog();
laika.makeNoise();

Video: https://youtu.be/62J_eQsK0e0?t=876


TS2454

error TS2454: Variable ‘myFavoriteNumber’ is used before being assigned.

Bad Code ❌

1
2
3
4
export function myNumber(): number {
let myFavoriteNumber: number;
return myFavoriteNumber;
}

Fixed Code ✔️

1
2
3
4
5
export function myNumber(): number {
let myFavoriteNumber: number;
myFavoriteNumber = 72;
return myFavoriteNumber;
}

or

1
2
3
4
export function myNumber(): number {
let myFavoriteNumber: number = 72;
return myFavoriteNumber;
}

TS2475

error TS2475: ‘const’ enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.

Bad Code ❌

1
2
3
4
5
6
7
export const enum TIME_INTERVAL {
ONE_MINUTE = "1m",
THREE_MINUTES = "3m",
FIVE_MINUTES = "5m",
}

console.log(Object.values(TIME_INTERVAL));

Fixed Code ✔️

Defining a const enum prevents TypeScript from generating JavaScript code for this enum. With const enum TypeScript will just assume that the JavaScript equivalent of this code is already present.

If you want that TypeScript creates JS code for your enum definition, then you have to remove the const keyword:

1
2
3
4
5
6
7
export enum TIME_INTERVAL {
ONE_MINUTE = "1m",
THREE_MINUTES = "3m",
FIVE_MINUTES = "5m",
}

console.log(Object.values(TIME_INTERVAL));

TS2488

error TS2488: Type ‘{ [month: number]: string; }’ must have a ‘Symbol.iterator‘ method that returns an iterator.

Solution

You have to add a property called [Symbol.iterator] to your object. The value of this property has to return an iterator. Here you can learn how to create an iterator.

Alternative Solution

If you run into this problem because of a for-of loop, then you can mitigate the problem by using the forEach() method of arrays:

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
const months: {
[month: number]: string;
} = {
1: 'January',
2: 'February',
};

for (const month of months) {
console.log(month);
}

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
10
const months: {
[month: number]: string;
} = {
1: 'January',
2: 'February',
};

Object.entries(months).forEach(month => {
console.log(month);
});

TS2497

error TS2497: Module ‘logdown‘ resolves to a non-module entity and cannot be imported using this construct.

Bad Code ❌

Export: logdown.d.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
declare class Logdown {
constructor(options?: Object);
public debug(...args: any[]): void;
public error(...args: any[]): void;
public info(...args: any[]): void;
public log(...args: any[]): void;
public warn(...args: any[]): void;
public static disable(...args: string[]): void;
public static enable(...args: string[]): void;
}

declare module "logdown" {
export = Logdown
}

Import: app.ts

1
import {Logdown} from "logdown";

Bad Code ❌ #2

Export

1
2
3
4
5
6
7
8
9
10
11
12
13
14
declare module 'logdown' {
class Logdown {
constructor(options?: Object);
public debug(...args: any[]): void;
public error(...args: any[]): void;
public info(...args: any[]): void;
public log(...args: any[]): void;
public warn(...args: any[]): void;
public static disable(...args: string[]): void;
public static enable(...args: string[]): void;
}

export = Logdown;
}

Import

1
2
3
import {Logdown} from "logdown";
...
this.logger = new Logdown({prefix: 'abc', alignOuput: true});

Note: tsc option “allowSyntheticDefaultImports” must be set to true

Import

1
import Logdown = require('logdown');

TS2503

error TS2503: Cannot find namespace ‘Proteus’

Bad Code ❌

1
import Proteus from "wireapp-proteus";

Fixed Code ✔️

1
import {Proteus} from "wireapp-proteus";

TS2503

Cannot find name ‘process’. Do you need to install type definitions for node? Try npm i --save-dev @types/node.

Solution

Run yarn add --dev @types/node in your npm project.


TS2507

error TS2507: Type ‘typeof EventEmitter‘ is not a constructor function type.

Error happened when importing the exported class in another project.

Bad Code ❌

1
2
3
4
5
6
7
import EventEmitter from 'events';

export class WebSocketClient extends EventEmitter {
constructor() {
super();
}
}

Fixed Code ✔️

1
2
3
4
5
6
7
import {EventEmitter} from 'events';

export class WebSocketClient extends EventEmitter {
constructor() {
super();
}
}
Read more

TS2511

error TS2511: Cannot create an instance of an abstract class.

Bad Code ❌

1
2
3
myFunction = (strategyConstructor: typeof Strategy, config: StrategyConfig): Promise<Big> => {
// ....
}

Fixed Code ✔️

1
2
3
4
5
export interface Type<T> extends Function { new (...args: any[]): T; }

myFunction = (strategyConstructor: StrategyType<Strategy<StrategyConfig>>, config: StrategyConfig): Promise<Big> => {
// ....
}

Read more: Passing a class constructor as parameter to a function.


TS2515

error TS2515: Non-abstract class ‘Dog’ does not implement inherited abstract member ‘makeNoise’ from class ‘Animal’.

Bad Code ❌

1
2
3
4
5
abstract class Animal {
abstract makeNoise(): string;
}

class Dog extends Animal {}

Fixed Code ✔️

If we derive a class from an abstract class, then we have to provide an implementation for all its abstract members:

1
2
3
4
5
6
7
8
9
abstract class Animal {
abstract makeNoise(): string;
}

class Dog extends Animal {
makeNoise(): string {
return 'Woof!';
}
}

Video: https://youtu.be/62J_eQsK0e0?t=708


TS2532

error TS2532: Object is possibly ‘undefined’.

Bad Code ❌

1
2
3
if (queueObject) {
queueObject.retry -= 1;
}

Fixed Code ✔️

1
2
3
if (queueObject) {
queueObject.retry! -= 1;
}

Bad Code ❌

1
const ownerIds: string[] = process.env.WIRE_OWNER_IDS.split(',')

Fixed Code ✔️

1
const ownerIds: string[] = String(process.env.WIRE_OWNER_IDS).split(',')

TS2554

error TS2554: Expected 2 arguments, but got 1.

Bad Code ❌

1
2
3
4
5
function printName(firstName: string, lastName: string): void {
console.log(`${firstName} ${lastName}`);
}

printName('Michael');

Fixed Code ✔️

1
2
3
4
5
function printName(firstName: string, lastName: string): void {
console.log(`${firstName} ${lastName}`);
}

printName('Michael', 'Jordan');

TS2564

error TS2564: Property ‘name’ has no initializer and is not definitely assigned in the constructor.

This error can occur with TypeScript 2.7 in “strict” mode. TypeScript 2.7 introduced a new flag called --strictPropertyInitialization, which tells the compiler to check that each instance property of a class gets initialized in the constructor body, or by a property initializer. See Strict Class Initialization.

Bad Code ❌

1
2
3
class Dog {
private name: string;
}

Fixed Code ✔️

We have to initialize the name member either at its definition or within the constructor.

Solution 1:

1
2
3
class Dog {
private name: string = 'Laika';
}

Solution 2:

1
2
3
4
5
6
7
class Dog {
private name: string;

constructor() {
this.name = 'Laika';
}
}

Solution 3:

1
2
3
4
class Dog {
constructor(private name: string = 'Laika') {
}
}

TS2571

error TS2571: Object is of type ‘unknown’.

Bad Code ❌

If you use third-party libraries then it can happen that TypeScript cannot infer all return types. In such a case a return type can be unknown which makes it impossible to access its properties from TypeScript. In the following example such case is constructed by assigning unknown to an exemplary constant:

1
2
const x: unknown = 1337;
console.log(x.toString());

Fixed Code ✔️

To solve the problem of accessing properties from an unknown object, we have to define the type of the object which we want to access:

1
2
const x: number = 1337;
console.log(x.toString());

TS2584

error TS2584: Cannot find name ‘console’. Do you need to change your target library? Try changing the ‘lib’ compiler option to include ‘dom’.

Bad Code ❌

TypeScript code:

1
console.log('Hello, World!');

TypeScript compiler configuration (tsconfig.json):

1
2
3
4
5
{
"compilerOptions": {
"lib": ["es2017"]
}
}

Fixed Code ✔️

You have to add the following to your tsconfig.json file:

1
2
3
4
5
{
"compilerOptions": {
"lib": ["es2017", "dom"]
}
}

When you are working on an application which never runs in a browser but only in Node.js environments, then you could add @types/node to your devDependencies instead of adding "dom" to your "lib" section.


TS2654

error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.

Bad Code ❌

1
/// <reference path="../../../typings/index.d.ts" />

Fix

Video: https://youtu.be/62J_eQsK0e0?t=401


TS2656

error TS2656: Exported external package typings file ‘../proteus.d.ts‘ is not a module. Please contact the package author to update the package definition.

Bad Code ❌

1
2
declare module Proteus {
}

Fixed Code ✔️

1
2
export module Proteus {
}

TS2668

error TS2668: ‘export’ modifier cannot be applied to ambient modules and module augmentations since they are always visible.

Info

Ambient modules

To describe the shape of libraries not written in TypeScript, we need to declare the API that the library exposes. We call declarations that don’t define an implementation “ambient”. Typically, these are defined in .d.ts files. If you’re familiar with C/C++, you can think of these as .h files.

Source: https://www.typescriptlang.org/docs/handbook/modules.html

Module Augmentation

With module augmentation, users have the ability to extend existing modules such that consumers can specify if they want to import the whole module or just a subset.

Source: https://blogs.msdn.microsoft.com/typescript/2016/02/22/announcing-typescript-1-8-2/

Bad Code ❌

1
2
3
export module 'amplify' {
export function publish(topic: string, ...args: any[]): boolean;
}

Fixed Code ✔️

1
export function publish(topic: string, ...args: any[]): boolean;

Usage

1
import amplify = require("amplify");

TS2669

error TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.

Solution

Bad Code ❌

1
2
3
4
5
6
7
declare global {
namespace NodeJS {
interface Global {
__coverage__: {};
}
}
}

You have to turn your code into a module by adding an import or export statement to your code. The easiest way to solve the problem is exporting an empty object:

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
declare global {
namespace NodeJS {
interface Global {
__coverage__: {};
}
}
}

export {}

TS2686

error TS2686: ‘ko’ refers to a UMD global, but the current file is a module. Consider adding an import instead.

Bad Code ❌

1
const downloadProgress = ko.observable();

Fixed Code ✔️

1
2
3
import ko from 'knockout';

const downloadProgress = ko.observable();

TS2686: ‘sinon’ refers to a UMD global, but the current file is a module. Consider adding an import instead.

Bad Code ❌

1
2
import { SinonFakeServer } from 'sinon';
let server: SinonFakeServer;

Fixed Code ✔️

1
2
import * as sinon from 'sinon';
let server: sinon.SinonFakeServer;

TS2689

error TS2689: Cannot extend an interface ‘Animal’. Did you mean ‘implements’?

Bad Code ❌

1
2
3
4
5
6
7
interface Animal {
name: string;
}

class Dog extends Animal {
name = 'Default Dog';
}

Fixed Code ✔️

The TypeScript compiler tells us already the solution: When implementing an interface, we have to use implements. If we inherit from classes, we use extends.

1
2
3
4
5
class Dog extends Animal {
protected makeNoise(): string {
return "Woof!";
}
}

TS2693

error TS2693: ‘Candlestick‘ only refers to a type, but is being used as a value here.

Bad Code ❌

main.ts

1
2
import Candlestick from "../../chart/Candlestick"
const candle = new Candlestick();

Candlestick.ts

1
2
3
4
5
6
7
8
interface Candlestick {
close: number
high: number
low: number
open: number
}

export default Candlestick

Fixed Code ✔️

main.ts

1
2
import Candlestick from "../../chart/Candlestick"
const candle = new Candlestick();

Candlestick.ts

1
2
3
4
5
6
7
8
class Candlestick {
close: number = 0
high: number = 0
low: number = 0
open: number = 0
}

export default Candlestick

TS2715

error TS2715: Abstract property ‘name’ in class ‘Animal’ cannot be accessed in the constructor.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
abstract class Animal {
abstract name: string;
}

class Dog extends Animal {
constructor(name: string) {
super();
this.name = name;
}
}

Fixed Code ✔️

The name member of the abstract Animal class is abstract, so we have to define it ourselves in the derived class Dog. Because name has no access modifier, it is public by default which means that our Dog class has to implement it with a public visibility:

1
2
3
4
5
6
7
8
9
10
11
12
abstract class Animal {
abstract name: string;
}

class Dog extends Animal {
public name;

constructor(name: string) {
super();
this.name = name;
}
}

TS2720

error TS2720: Class ‘Dog’ incorrectly implements class ‘Animal’. Did you mean to extend ‘Animal’ and inherit its members as a subclass?   Property ‘makeNoise’ is protected but type ‘Dog’ is not a class derived from ‘Animal’.

Bad Code ❌

1
2
3
abstract class Animal {
protected abstract makeNoise(): string;
}

Fixed Code ✔️

The implements keyword is reserved to implement interfaces. If you want to work with class inheritance, you have to use extends:

1
2
3
4
5
class Dog extends Animal {
protected makeNoise(): string {
return "Woof!";
}
}

Video: https://youtu.be/62J_eQsK0e0?t=591


TS2741

error TS2741: Property ‘name’ is missing in type ‘{}’ but required in type ‘Animal’.

Bad Code ❌

1
2
3
4
5
interface Animal {
name: string;
}

const laika: Animal = {};

Fixed Code ✔️

Interfaces can be used with classes or plain objects. If we want our object (i.e. laika) to fulfill the contract of Animal, we have to assign all required properties to it:

1
2
3
4
5
6
7
interface Animal {
name: string;
}

const laika: Animal = {
name: 'Laika',
};

Video: https://www.youtube.com/watch?v=62J_eQsK0e0&t=1155s


TS2769

error TS2769: No overload matches this call.

Bad Code ❌

1
const sessions = [].concat(...bestConfigs);

Fixed Code ✔️

When proving just an empty array ([]), then TypeScript does not know what type of elements can be stored in this array. That’s why there is no overload which matches when adding values from a typed array (such as bestConfigs) to an untyped array. The solution here is to provide a typed array of the same type as the array that is being used for concatenation.

1
2
3
4
5
const sessions = ([] as Config[]).concat(...bestConfigs);

// Alternative:
const typedArray: Config[] = [];
const sessions = typedArray.concat(...bestConfigs);

TS2794

error TS2794: Expected 1 arguments, but got 0. Did you forget to include ‘void’ in your type argument to ‘Promise’?

Solution

When a Promise resolves with nothing, then you need to define this return type (void) in recent versions of TypeScript.

Bad Code ❌

1
await new Promise((resolve, reject) => { resolve(); });

Fixed Code ✔️

1
await new Promise<void>((resolve, reject) => { resolve(); });

TS2813

error TS2813: Class declaration cannot implement overload list for ‘MyClass’.

Solution

Bad Code ❌

1
2
3
4
5
class MyClass {
}

function MyClass(): void {
}

Function declarations get hoisted, so you cannot give your class the name of your function. Renaming your class solves the issue:

Fixed Code ✔️

1
2
3
4
5
class MyClassWithAnotherName {
}

function MyClass(): void {
}

TS2814

error TS2814: Function with bodies can only merge with classes that are ambient.

Solution

Bad Code ❌

1
2
3
4
5
class MyClass {
}

function MyClass(): void {
}

Your function cannot be named after your class, so you will have to rename your function:

Fixed Code ✔️

1
2
3
4
5
class MyClass {
}

function MyFunctionWithAnotherName(): void {
}

Alternatively you can declare an ambient class which gets implemented by your function:

1
2
3
4
5
declare class MyClass {
}

function MyClass(): void {
}

TS4020

error TS4020: ‘extends’ clause of exported class ‘StrategyPOJO‘ has or is using private name ‘Model‘.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
const {Model} = require('objection')

class StrategyPOJO extends Model {
static tableName = 'strategies'
config: string | undefined
exchange: string | undefined
identifier: string | undefined
symbol: string | undefined
}

export {StrategyPOJO}

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
10
11
import {Model} from 'objection'

class StrategyPOJO extends Model {
static tableName = 'strategies'
config: string | undefined
exchange: string | undefined
identifier: string | undefined
symbol: string | undefined
}

export {StrategyPOJO}

TS4063

error TS4063: Parameter ‘config‘ of constructor from exported class has or is using private name ‘DoubleMovingAverageConfig‘.

Bad Code ❌

1
2
3
4
5
6
7
8
9
type DoubleMovingAverageConfig = {
lastBuyPrice: string,
lastSellPrice: string,
warmUpCandles: number,
}

class DoubleMovingAverage extends Strategy {
constructor(private setup: StrategySetup, private config?: DoubleMovingAverageConfig) {}
}

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
export type DoubleMovingAverageConfig = {
lastBuyPrice: string,
lastSellPrice: string,
warmUpCandles: number,
}

class DoubleMovingAverage extends Strategy {
constructor(private setup: StrategySetup, private config?: DoubleMovingAverageConfig) {}
}

TS4075

error TS4075: Parameter ‘event’ of method from exported interface has or is using private name ‘Strategy’.

Bad Code ❌

1
2
3
4
5
6
7
8
9
10
11
export interface Strategy<SpecificConfig extends StrategyConfig> {
on(event: Strategy.TOPIC.TRADER_DELETE, listener: () => void): this;
}

export abstract class Strategy<SpecificConfig extends StrategyConfig> extends EventEmitter {
static readonly TOPIC = {
TRADER_DELETE: 'TRADER_DELETE'
};

// ...
}

Fixed Code ✔️

1
2
3
4
5
6
7
8
9
10
11
12
13
enum TOPIC {
TRADER_DELETE = 'TRADER_DELETE'
}

export interface Strategy<SpecificConfig extends StrategyConfig> {
on(event: TOPIC.TRADER_DELETE, listener: () => void): this;
}

export abstract class Strategy<SpecificConfig extends StrategyConfig> extends EventEmitter {
static readonly TOPIC = TOPIC;

// ...
}

TS5055

error TS5055: Cannot write file ‘/Users/bennyn/projects/wireapp/wire-webapp-lru-cache/dist/commonjs/LRUCache.d.ts‘ because it would overwrite input file.

Bad Code ❌

tsconfig.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"compilerOptions": {
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "dist/commonjs",
"removeComments": true,
"rootDir": "src/main/ts",
"sourceMap": false,
"target": "es5"
},
"exclude": [
"bower_components",
"node_modules",
"typings/browser",
"typings/browser.d.ts"
]
}

Fixed Code ✔️

tsconfig.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"compilerOptions": {
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"outDir": "dist/commonjs",
"removeComments": true,
"rootDir": "src/main/ts",
"sourceMap": false,
"target": "es5"
},
"exclude": [
"bower_components",
"dist/commonjs",
"node_modules",
"typings/browser",
"typings/browser.d.ts"
]
}

TS6053

error TS6053: File ‘/typings/index.d.ts‘ not found.

Bad Code ❌

1
/// <reference path='/typings/index.d.ts' />

Fixed Code ✔️

Use relative paths when using Triple-Slash Directives:

1
/// <reference path='../../../typings/index.d.ts' />

Read more: 8 Steps to Migrating from JavaScript to TypeScript


TS6059

error TS6059: File ‘/root/project/packages/server/package.json‘ is not under ‘rootDir’ ‘/root/project/packages/server/src‘. ‘rootDir’ is expected to contain all source files.

Bad Code ❌

1
import pkg from '../../../../package.json';

Fixed Code ✔️

1
const pkg = require('../../../../package.json');

TS6133

error TS6133: ‘volume‘ is declared but its value is never read.

Bad Code ❌

test.ts
1
const closes = ohlc.map(([time, open, high, low, close, volume]) => (close));
tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"noUnusedParameters": true
}
}

Fixed Code ✔️

tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"noUnusedParameters": false
}
}

error TS6133: ‘b‘ is declared but its value is never read.

test.ts
1
let b;
tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"noUnusedLocals": true
}
}

Fixed Code ✔️

tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"noUnusedLocals": false
}
}

Video: https://youtu.be/62J_eQsK0e0?t=78


TS6196

error TS6196: ‘MyAbstractClass’ is declared but never used.

Bad Code ❌

1
2
3
abstract class MyAbstractClass {
abstract getResult(): boolean;
}

Fixed Code ✔️

You have three possibilities to fix the broken code:

  1. Make use of MyAbstractClass in your application
  2. Export MyAbstractClass
  3. Set noUnusedLocals to false in your tsconfig.json
1
2
3
export abstract class MyAbstractClass {
abstract getResult(): boolean;
}

TS7006

error TS7006: Parameter ‘person‘ implicitly has an ‘any’ type.

Bad Code ❌

test.ts

1
2
3
function greeter(person) {
return "Hello, " + person;
}

tsconfig.json

1
"noImplicitAny": true

Fixed Code ✔️

test.ts

1
2
3
function greeter(person: string) {
return "Hello, " + person;
}

TS7016

error TS7016: Could not find a declaration file for module ‘uuidjs‘.

Bad Code ❌

1
import UUID = require('uuidjs');

Fixed Code ✔️

1
const UUID = require('uuidjs');

Note: Proper fix would be to have a uuidjs.d.ts: https://github.com/LiosK/UUID.js/issues/6


TS7017

error TS7017: Element implicitly has an ‘any’ type because type ‘{}’ has no index signature.

Bad Code ❌

1
const recipients = {};

Fixed Code ✔️

1
const recipients: {[index: string]: number} = {};

How to fix such errors in interfaces:

1
2
3
export interface DexieInstance extends Dexie{
[index: string]: any;
}

Alternative:


TS7027

error TS7027: Unreachable code detected.

Bad Code ❌

1
2
process.exit(0);
console.log('Hello, World!');

Fixed Code ✔️

1
console.log('Hello, World!');

TS7034

error TS7034: Variable ‘expectations’ implicitly has type ‘any[]’ in some locations where its type cannot be determined.

Bad Code ❌

1
let expectations = [];

Fixed Code ✔️

1
let expectations: string[] = [];

Unrecommended solutions: You can set noImplicitAny to false or strict to false in your tsconfig.json.