Common Errors

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

  1. 1. TS1002
  2. 2. TS1005
  3. 3. TS1006
  4. 4. TS1016
  5. 5. TS1029
  6. 6. TS1036
  7. 7. TS1046
  8. 8. TS1055
  9. 9. TS1066
  10. 10. TS1070
  11. 11. TS1109
  12. 12. TS1117
  13. 13. TS1127
  14. 14. TS1149
  15. 15. TS1155
  16. 16. TS1160
  17. 17. TS1192
  18. 18. TS1196
  19. 19. TS1202
  20. 20. TS1208
  21. 21. TS1218
  22. 22. TS1219
  23. 23. TS1228
  24. 24. TS1243
  25. 25. TS1244
  26. 26. TS1259
  27. 27. TS1308
  28. 28. TS1337
  29. 29. TS1375
  30. 30. TS1378
  31. 31. TS1434
  32. 32. TS17000
  33. 33. TS17009
  34. 34. TS18004
  35. 35. TS2300
  36. 36. TS2304
  37. 37. TS2305
  38. 38. TS2306
  39. 39. TS2307
  40. 40. TS2314
  41. 41. TS2315
  42. 42. TS2322
  43. 43. TS2335
  44. 44. TS2339
  45. 45. TS2345
  46. 46. TS2348
  47. 47. TS2349
  48. 48. TS2351
  49. 49. TS2352
  50. 50. TS2355
  51. 51. TS2365
  52. 52. TS2366
  53. 53. TS2368
  54. 54. TS2370
  55. 55. TS2371
  56. 56. TS2377
  57. 57. TS2378
  58. 58. TS2391
  59. 59. TS2394
  60. 60. TS2411
  61. 61. TS2420
  62. 62. TS2428
  63. 63. TS2445
  64. 64. TS2448
  65. 65. TS2454
  66. 66. TS2475
  67. 67. TS2488
  68. 68. TS2497
  69. 69. TS2503
  70. 70. TS2507
  71. 71. TS2511
  72. 72. TS2515
  73. 73. TS2532
  74. 74. TS2538
  75. 75. TS2554
  76. 76. TS2556
  77. 77. TS2564
  78. 78. TS2571
  79. 79. TS2580
  80. 80. TS2582
  81. 81. TS2584
  82. 82. TS2588
  83. 83. TS2613
  84. 84. TS2616
  85. 85. TS2654
  86. 86. TS2656
  87. 87. TS2668
  88. 88. TS2669
  89. 89. TS2680
  90. 90. TS2683
  91. 91. TS2684
  92. 92. TS2686
  93. 93. TS2689
  94. 94. TS2691
  95. 95. TS2693
  96. 96. TS2695
  97. 97. TS2715
  98. 98. TS2720
  99. 99. TS2730
  100. 100. TS2732
  101. 101. TS2739
  102. 102. TS2741
  103. 103. TS2769
  104. 104. TS2794
  105. 105. TS2813
  106. 106. TS2814
  107. 107. TS4020
  108. 108. TS4025
  109. 109. TS4063
  110. 110. TS4075
  111. 111. TS4112
  112. 112. TS4113
  113. 113. TS4114
  114. 114. TS5025
  115. 115. TS5055
  116. 116. TS6053
  117. 117. TS6059
  118. 118. TS6133
  119. 119. TS6196
  120. 120. TS6198
  121. 121. TS6504
  122. 122. TS7006
  123. 123. TS7016
  124. 124. TS7017
  125. 125. TS7027
  126. 126. TS7030
  127. 127. TS7031
  128. 128. TS7034
  129. 129. TS7041
  130. 130. TS7053
  131. 131. TS8020

TS1002

error TS1002: Unterminated string literal.

Broken Code ❌

1
const text = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr

Fixed Code ✔️

You have to close the string literal with an ending ':

1
const text = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr';

If you want to support multiline text, then you would have to use string concatenation:

1
2
const text = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, ' +
'sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.';

Another solution would be using a template literal:

1
2
const text = `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, 
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.`;

TS1005

error TS1005: ‘=’ expected.

Broken Code ❌

1
2
3
4
type Person {
age: number;
name: string;
}

Fixed Code ✔️

You need to assign your type declaration using the = character:

1
2
3
4
type Person = {
age: number;
name: string;
}

Alternatively you can declare an interface:

1
2
3
4
interface Person {
age: number;
name: string;
}

TS1006

error TS1006: A file cannot have a reference to itself.

Broken Code ❌

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

Fixed Code ✔️

You cannot reference a file to itself (causes recursive loop). To fix the problem you have to update the reference path to point to another declaration file:

index.d.ts
1
/// <reference path='some-other-file.d.ts' />

TS1016

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

Broken 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.

Broken 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 Tutorial


TS1036

error TS1036: Statements are not allowed in ambient contexts.

Broken 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;
}

If you don’t want client to be a function, you have to use thevar` keyword:

1
2
3
declare global {
var client: APIClient;
}

TS1046

error TS1046: Top-level declarations in .d.ts files must start with either a ‘declare’ or ‘export’ modifier.

Broken Code ❌

index.d.ts
1
const MAGIC_NUMBER = 1337;

Fixed Code ✔️

If you want to export a constant from a definition file (d.ts), then you have to use the export modifier:

index.d.ts
1
export const MAGIC_NUMBER = 1337;

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.

Broken 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.

Broken Code ❌

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

Fixed Code ✔️

Try to replace your enum declaration with a type:

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

TS1070

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

Broken 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 Tutorial


TS1109

error TS1109: Expression expected.

Broken Code ❌

1
const lastName = throw new Error('Missing last name');

Fixed Code ✔️

Any snippet of code that evaluates to a value is an expression. Any snippet of code that performs an action is a statement. We need a statement to throw an error inside:

1
2
3
4
const lastName = undefined;
if (!lastName) {
throw new Error('Missing last name');
}

TS1117

error TS1117: An object literal cannot have multiple properties with the same name in strict mode.

Broken Code ❌

1
2
3
4
const objectLiteral = {
name: 'Benny',
name: 'Sofia'
};

Fixed Code ✔️

We can only have one value per property:

1
2
3
const objectLiteral = {
name: 'Benny'
};

TS1127

error TS1127: Invalid character.

Broken Code ❌

1
# My comment

Fixed Code ✔️

Unlike in Python, inline comments cannot begin with a single hash sign (#) in TypeScript. You must use 3 slashes:

1
// My comment

TS1149

TS1149: File name differs from already included file name only in casing.

Broken Code ❌

This error occurs when you import the same file in two different files using two different casing styles (ex. camelCase and UpperCamelCase):

File A:

1
import { BaseTestPage } from './baseTestPage';

File B:

1
import { BaseTestPage } from './BaseTestPage';

Fixed Code ✔️

The error can be fixed by using the same casing style:

File A:

1
import { BaseTestPage } from './BaseTestPage';

File B:

1
import { BaseTestPage } from './BaseTestPage';

Alternatively, you can set forceConsistentCasingInFileNames to false in your “tsconfig.json” file:

tsconfig.json

1
2
3
4
5
{
"compilerOptions": {
"forceConsistentCasingInFileNames": false
}
}

TS1155

error TS1155: ‘const’ declarations must be initialized.

Broken Code ❌

1
const name: string;

Fixed Code ✔️

1
const name: string = 'Benny';

Alternatively you can define a block-scoped local variable:

1
let name: string;

TS1160

error TS1160: Unterminated template literal.

Broken Code ❌

1
2
const text = `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, 
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.

Fixed Code ✔️

This error is similar to TS1002 but refers to the ending of a template literal. To fix it, we have to close the template literal with an ending `:

1
2
const text = `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, 
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.`;

TS1192

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

Broken Code ❌

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

export = Logdown;

Fixed Code ✔️

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

export default Logdown;

error TS1192: ‘export *’ does not re-export a default.

Broken Code ❌

1
2
export * from './parseUrls';
export * from './runWhenReady';

You have to re-export a default (in this case coming from runWhenReady.ts):

Fixed Code ✔️

1
2
3
export * from './parseUrls';
export * from './runWhenReady';
export { default as default } from './runWhenReady';

TS1196

error TS1196: Catch clause variable type annotation must be ‘any’ or ‘unknown’ if specified.

Broken Code ❌

1
2
3
4
5
6
7
8
9
type MyError = {
code: number
}

try {
// ...
} catch (error: MyError) {
console.log(error.code);
}

Fixed Code ✔️

Errors in catch clauses can only be typed with any or unknown. If you need a more precise error typing, you can use a type guard as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Type Guard
function isMyError(error: any): error is MyError {
return typeof error.code === 'number';
}

type MyError = {
code: number
}

try {
// ...
} catch (error: unknown) {
if (isMyError(error)) {
console.log(error.code);
}
}

Video Tutorial


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.

Broken 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.

Broken 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’.

Broken Code ❌

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

export = LRUCache;

Fixed Code ✔️

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

TS1219

error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the ‘experimentalDecorators’ option in your ‘tsconfig’ or ‘jsconfig’ to remove this warning.

Broken Code ❌

1
2
3
4
5
6
7
8
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}

Fixed Code ✔️

Simply set “experimentalDecorators” to true in your “tsconfig.json” file. As long as decorators are experimental you will also have to install the reflect-metadata package to shim the upcoming Metadata Reflection API for ECMAScript. For proper functionality the “emitDecoratorMetadata” option should also be set to true.


TS1228

error TS1228: A type predicate is only allowed in return type position for functions and methods.

Broken Code ❌

1
2
3
function hasErrorCode(error: any) error is {code: string} {
return typeof (error && error.code) === 'string'
}

Fixed Code ✔️

You have to separate the argument list from the return type definition by a ::

1
2
3
function hasErrorCode(error: any): error is {code: string} {
return typeof (error && error.code) === 'string'
}

TS1243

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

Solution

Broken 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;
};
}

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

Broken Code ❌

1
abstract async goto(): Promise<void>;

Fixed Code ✔️

1
abstract goto(): Promise<void>;

TS1244

error TS1244: Abstract methods can only appear within an abstract class.

Broken Code ❌

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

Fixed Code ✔️

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

TS1259

error TS1259: Module can only be default-imported using the ‘esModuleInterop’ flag

Broken Code ❌

1
tsc mycode.js --allowJs --noEmit 

Fixed Code ✔️

1
tsc mycode.js --allowJs --noEmit --esModuleInterop

TS1308

error TS1308: ‘await’ expressions are only allowed within async functions and at the top levels of modules.ts.

Broken Code ❌

1
2
3
4
5
React.useEffect(() => {
const myPromise = Promise.resolve;
await myPromise();
console.log('Promise is resolved.');
}, []);

Fixed Code ✔️

You cannot use an await expression in an useEffect hook, but you can use legacy Promise calls:

1
2
3
4
5
6
React.useEffect(() => {
const myPromise = Promise.resolve;
myPromise().then(() => {
console.log('Promise is resolved.');
});
}, []);

Alternatively, you can use an IIFE (Immediately-invoked Function Expression) in your useEffect hook:

1
2
3
4
5
React.useEffect(() => {
(async () => {
await Promise.resolve();
})();
}, []);

TS1337

error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.

Broken Code ❌

1
2
3
export interface StreetMap {
[city: 'New York']: ['Broadway', 'Park Avenue'];
}

Fixed Code ✔️

1
2
3
export type StreetMap = {
'New York': ['Broadway', 'Park Avenue'];
};

Alternative:

1
2
3
export interface StreetMap {
[city: string]: ['Broadway', 'Park Avenue'];
}

error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead.

Broken Code ❌

1
2
3
4
5
6
7
interface CustomError {
[key: string | number]: string | number;
}

const error: CustomError = {
401: 'Unauthorized',
};

Fixed Code ✔️

Solution with mapped object type:

1
2
3
4
5
6
7
type CustomError = {
[key in number | string]: string | number;
};

const error: CustomError = {
401: 'Unauthorized',
};

Alternative:

1
2
3
4
5
6
7
8
9
10
11
interface ErrorNumber {
[key: number]: string | number;
}

interface ErrorString {
[key: string]: string | number;
}

const error: ErrorNumber | ErrorString = {
401: 'Unauthorized',
};

TS1375

error TS1375: ‘await’ expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty ‘export {}’ to make this file a module.

Broken Code ❌

1
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');

Fixed Code ✔️

1
2
3
export {};

const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');

TS1378

error TS1378: Top-level ‘await’ expressions are only allowed when the ‘module’ option is set to ‘es2022’, ‘esnext’, ‘system’, or ‘nodenext’, and the ‘target’ option is set to ‘es2017’ or higher.

Broken Code ❌

tsconfig.json

1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
"lib": ["es2017"],
"module": "commonjs",
"outDir": "dist",
"rootDir": "src",
"target": "es6"
}
}

Fixed Code ✔️

tsconfig.json

1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
"lib": ["es2017"],
"module": "esnext",
"outDir": "dist",
"rootDir": "src",
"target": "es2017"
}
}

TS1434

error TS1434: Unexpected keyword or identifier.

Broken Code ❌

1
2
3
class MyClass {
static static ID: number = 1337;
}

Fixed Code ✔️

You have to remove the duplicate static keyword:

1
2
3
class MyClass {
static ID: number = 1337;
}

TS17000

error TS17000: JSX attributes must only be assigned a non-empty ‘expression’.

Broken Code ❌

1
<Typography variant={}>Title</Typography>

Fixed Code ✔️

You can’t use an empty expression ({}) in JSX attributes:

1
<Typography variant={'h2'}>Title</Typography>

TS17009

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

Broken 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.

Broken 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',
};
}

TS2300

error TS2300: Duplicate identifier ‘name’.

Broken Code ❌

Objects don’t support multiple properties with the same name:

1
2
3
4
const objectLiteral = {
name: 'Benny',
name: 'Sofia'
};

Fixed Code ✔️

To fix the error we have to remove the duplicated property:

1
2
3
const objectLiteral = {
name: 'Sofia'
};

TS2304

error TS2304: Cannot find name ‘world’.

Broken 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);

error TS2304: Cannot find name ‘Promise’

Broken 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);
});
}

...

error TS2304: Cannot find name ‘Promise’

Broken Code ❌

1
const UUID = require('uuidjs');

Fixed Code ✔️

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

error TS2304: Cannot find name ‘FC’.

Broken Code ❌

1
2
3
4
5
import React from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

Fixed Code ✔️

1
2
3
4
5
import React, {FC} from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

TS2305

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

Broken Code ❌

1
2
declare module keys {
}

Fixed Code ✔️

1
2
export module keys {
}

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

Broken Code ❌

1
2
export module keys {
}

Fixed Code ✔️

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

TS2306

error TS2306: File ‘add.ts‘ is not a module.

Broken Code ❌

add.ts
1
2
3
function add(a: number, b: number): number {
return a + b;
}
main.ts
1
2
3
import { add } from './add';

console.log(add(1000, 337));

Fixed Code ✔️

The error TS2306 signals that the file (add.ts) can be found (otherwise it would throw error TS2307) but does not provide the necessary exports. We can solve this with a named export:

add.ts
1
2
3
export function add(a: number, b: number): number {
return a + b;
}

Alternatively we can use a default export:

add.ts
1
2
3
export default function add(a: number, b: number): number {
return a + b;
}

Using a default export requires that we also adjust our import statement in main.ts (otherwise we would end up with error TS2614):

main.ts
1
2
3
import add from './add';

console.log(add(1000, 337));

TS2307

error TS2307: Cannot find module ‘events’ or its corresponding type declarations.

Broken Code ❌

You are importing from a core Node.js module (e.g. event) without having Node.js type definitions installed:

1
import {EventEmitter} from 'events';

Fixed Code ✔️

Import Node.js type definitions first in order to use Node.js core modules:

1
npm install @types/node

More: Error TS2307: Cannot find module events


TS2314

error TS2314: Generic type ‘Omit’ requires 2 type argument(s).

Broken Code ❌

1
2
3
4
export interface SerializedBatchedCandle extends Omit<BatchedCandle, 'close', 'open'> {
open: string;
close: string;
}

Fixed Code ✔️

When using the Omit utility type, you have to list property overwrites with a pipe (|):

1
2
3
4
export interface SerializedBatchedCandle extends Omit<BatchedCandle, 'close' | 'closeAsk'> {
close: string;
closeAsk: string;
}

TS2315

error TS2315: Type ‘CustomRequest‘ is not generic.

Broken Code ❌

1
2
3
4
5
6
7
8
9
type CustomRequest = {
url: string;
data: string;
}

const request: CustomRequest<string> = {
url: 'https://typescript.tv/',
data: 'example'
};

Fixed Code ✔️

When supplying a type (recognizable by the use of the diamond operator <>), then we have to make sure that our type actually supports generics to capture the type that we provide:

1
2
3
4
5
6
7
8
9
type CustomRequest<CustomType> = {
url: string;
data: CustomType;
}

const request: CustomRequest<string> = {
url: 'https://typescript.tv/',
data: 'example'
};

TS2322

error TS2322: Type ‘string’ is not assignable to type ‘number’.

Broken Code ❌

1
2
3
export function add(a: number, b: number): number {
return `${a + b}`;
}

Fixed Code ✔️

The type of the returned value must match the return type specified in the function signature:

1
2
3
export function add(a: number, b: number): number {
return parseInt(`${a + b}`, 10);
}

Video Tutorial


TS2335

error TS2335: ‘super’ can only be referenced in a derived class.

Broken Code ❌

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

class Cat {
constructor() {
super();
}

makeNoise(): string {
return 'Meow!';
}
}

Fixed Code ✔️

Your derived class has to “extend” the base class:

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

class Cat extends Animal {
constructor() {
super();
}

makeNoise(): string {
return 'Meow!';
}
}

TS2339

error TS2339: Property ‘width‘ does not exist on type ‘Shape‘.

Broken Code ❌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
type Shape = {
kind: 'rectangle' | 'square';
}

type Rectangle = {
kind: 'rectangle';
width: number;
height: number;
} & Shape

type Square = {
kind: 'square';
size: number;
} & Shape;

function handleShape(shape: Shape): void {
switch (shape.kind) {
case 'rectangle':
console.log(shape.width);
break;
case 'square':
console.log(shape.size);
break;
}
}

Fixed Code ✔️

You can create discriminated unions by sharing a single field (e.g. kind) in your type definitions and using a union type in connection with a switch-case statement that helps the TypeScript compiler to distinguish the different types:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type Rectangle = {
kind: 'rectangle';
width: number;
height: number;
}

type Square = {
kind: 'square';
size: number;
}

type Shape = Rectangle | Square;

function handleShape(shape: Shape): void {
switch (shape.kind) {
case 'rectangle':
console.log(shape.width);
break;
case 'square':
console.log(shape.size);
break;
}
}

TS2345

error TS2345: Argument of type ‘number‘ is not assignable to parameter of type ‘TimerHandler‘.

Broken Code ❌

1
2
3
4
5
function add(a: number, b: number): number {
return a + b;
}

setTimeout(add(1000, 337), 5000);

Fixed Code ✔️

There is a mismatch in the expected arguments of a function. The setTimeout function expects the first argument to be a callback function and not the returned value (in this case a number) of a function call:

1
2
3
4
5
function add(a: number, b: number): number {
return a + b;
}

setTimeout(() => add(1000, 337), 5000);

Video Tutorial


TS2348

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

Broken 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.

Broken 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.

Broken 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 ‘{ name: string; age: number; }‘ to type ‘Person‘ may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to ‘unknown‘ first.

Broken Code ❌

1
2
3
4
5
6
7
8
9
type Person = {
firstName: string;
age: number;
}

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

Fixed Code ✔️

Make sure all properties of your object match the properties of your declared type:

1
2
3
4
5
6
7
8
9
type Person = {
firstName: string;
age: number;
}

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

Alternative but not recommended: Convert your object to unknown first:

1
2
3
4
5
6
7
8
9
type Person = {
firstName: string;
age: number;
}

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

TS2355

error TS2355: A function whose declared type is neither ‘void’ nor ‘any’ must return a value.

Broken Code ❌

1
2
3
getName(): string {

}

Fixed Code ✔️

1
2
3
getName(): string {
return 'Benny';
}

TS2365

error TS2365: Operator ‘+’ cannot be applied to types ‘number’ and ‘object’.

Broken Code ❌

1
2
3
export function add(a: number, b: object): number {
return a + b;
}

Fixed Code ✔️

You can use the + operator only with equivalent data types (strings + strings or numbers + numbers):

1
2
3
export function add(a: number, b: number): number {
return a + b;
}

TS2366

error TS2366: Function lacks ending return statement and return type does not include ‘undefined’.

Broken Code ❌

1
2
3
4
5
6
7
8
export function getInterestRate(years: 1 | 2 | 3): number {
switch (years) {
case 1:
return 1.75;
case 2:
return 2.96;
}
}

Fixed Code ✔️

The switch-case statement isn’t handling all cases from every possible input. We can solve that by defining a default case:

1
2
3
4
5
6
7
8
9
10
export function getInterestRate(years: 1 | 2 | 3): number {
switch (years) {
case 1:
return 1.75;
case 2:
return 2.96;
default:
return 3;
}
}

Another solution would be to implement the missing case for 3:

1
2
3
4
5
6
7
8
9
10
export function getInterestRate(years: 1 | 2 | 3): number {
switch (years) {
case 1:
return 1.75;
case 2:
return 2.96;
case 3:
return 3;
}
}

Video Tutorial


TS2368

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

Broken 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.

Broken Code ❌

1
2
3
4
5
function sum(...array: number): number {
return array.reduce((a, b) => a + b);
}

console.log(sum(...[1, 2, 3, 4, 5]));

Fixed Code ✔️

A rest parameter allows a function to accept an indefinite number of parameters. To signal that it can be multiple values, we have to use an array type for our rest parameter:

1
2
3
4
5
function sum(...array: number[]): number {
return array.reduce((a, b) => a + b);
}

console.log(sum(...[1, 2, 3, 4, 5]));

TS2371

error TS2371: A parameter initializer is only allowed in a function or constructor implementation.

Broken Code ❌

1
2
3
4
function add(a: number, b: number, c: number = 0): number;
function add(a: number | string, b: number | string, c: number | string = 0): number {
return parseInt(`${a}`, 10) + parseInt(`${b}`, 10);
}

Fixed Code ✔️

Remove parameter initializer from function overload:

1
2
3
4
function add(a: number, b: number, c: number): number;
function add(a: number | string, b: number | string, c: number | string = 0): number {
return parseInt(`${a}`, 10) + parseInt(`${b}`, 10);
}

TS2377

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

Broken 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 Tutorial


TS2378

error TS2378: A ‘get’ accessor must return a value.

Broken Code ❌

1
2
3
get name() {

}

Fixed Code ✔️

1
2
3
get name(): string {
return 'Benny';
}

TS2391

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

Broken 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 Tutorial


TS2394

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

Broken Code ❌

The implementation does not match all signatures:

1
2
3
4
5
function sum(a: number, b: number): number;
function sum(a: string, b: string): string;
function sum(a: number | string, b: number | string) {
return `${parseInt(a + '', 10) + parseInt(b + '', 10)}`;
}

Fixed Code ✔️

To match the first function overload, we have to add code to our function body which can also return a number:

1
2
3
4
5
6
7
8
function sum(a: number, b: number): number;
function sum(a: string, b: string): string;
function sum(a: number | string, b: number | string) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
return `${parseInt(a + '', 10) + parseInt(b + '', 10)}`;
}

Video Tutorial


TS2411

error TS2411: Property ‘age’ of type ‘number’ is not assignable to ‘string’ index type ‘string’.

Broken Code ❌

1
2
3
4
5
interface Person {
[key: string]: string;
age: number;
name: string;
}

Fixed Code ✔️

We defined an interface where every key has a value of type string. This doesn’t work for age which is why we have to extend the possible value types using a union type:

1
2
3
4
5
interface Person {
[key: string]: number | string;
age: number;
name: string;
}

TS2420

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

Broken 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 Tutorial


TS2428

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

Broken 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.

Broken 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 Tutorial


TS2448

error TS2448: Block-scoped variable ‘add’ used before its declaration.

Broken Code ❌

Function expressions cannot be hoisted (used before they are declared):

1
2
3
4
5
add(1, 2);

const add = (a: number, b: number): number => {
return a + b;
};

Fixed Code ✔️

Turn your function expression into a function declaration (which can be hoisted):

1
2
3
4
5
add(1, 2);

function add(a: number, b: number): number {
return a + b;
}

TS2454

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

Broken 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.

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

Broken 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.

Broken 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";

Broken 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’

Broken Code ❌

1
import Proteus from "wireapp-proteus";

Fixed Code ✔️

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

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.

Broken 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.

Broken 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’.

Broken 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 Tutorial


TS2532

error TS2532: Object is possibly ‘undefined’.

Broken Code ❌

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

Fixed Code ✔️

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

Broken Code ❌

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

Fixed Code ✔️

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

TS2538

error TS2538: Type ‘Person’ cannot be used as an index type.

Broken Code ❌

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

function getValue(person: Person, key: Person): string {
return person[key];
}

Fixed Code ✔️

You cannot use an interface as an index type, but you can use all keys of the interface using the keyof type operator:

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

function getValue(person: Person, key: keyof Person): string {
return person[key];
}

TS2554

error TS2554: Expected 2 arguments, but got 1.

Broken 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');

Video Tutorial


TS2556

error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.

Broken Code ❌

1
2
3
4
5
function sum(a: number, b: number): number {
return a + b;
}

console.log(sum(1, ...[2, 3, 4, 5]));

Fixed Code ✔️

When calling a function using the spread syntax (...), we have to ensure that the called function uses a rest
parameter:

1
2
3
4
5
function sum(a: number, ...b: number[]): number {
return a + b.reduce((c, d) => c + d);
}

console.log(sum(1, ...[2, 3, 4, 5]));

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.

Broken 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') {
}
}

Video Tutorial


TS2571

error TS2571: Object is of type ‘unknown’.

Broken 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());

Alternative

You may also get the error “Object is of type ‘unknown’” when catching errors. In this case you have to type the error in your catch clause.


TS2580

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

Broken Code ❌

1
2
const path = require('path');
console.log(path.basename(__dirname));

Fixed Code ✔️

Install typings for Node.js:

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

Update code to modern import syntax:

1
2
import path from 'path';
console.log(path.basename(__dirname));

TS2582

error TS2582: Cannot find name ‘test’. Do you need to install type definitions for a test runner? Try npm i --save-dev @types/jest or npm i --save-dev @types/mocha.

Broken Code ❌

1
2
3
test('create sum', () => {
expect(1 + 2).toBe(3);
});

Fixed Code ✔️

The error above is very specific to your testing framework and when using Jest it can be easily solved by installing definition files for Jest (npm i --save-dev @types/jest).

When you are using Playwright, then you would have to make sure that you properly import Playwright’s definition for test:

1
2
3
4
5
import {test, expect} from '@playwright/test';

test('create sum', () => {
expect(1 + 2).toBe(3);
});

TS2584

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

Broken 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.


TS2588

error TS2588: Cannot assign to ‘name’ because it is a constant.

Broken Code ❌

1
2
const name = 'Benny';
name = 'Sofia';

Fixed Code ✔️

You cannot reassign values to constants which is why you have to declare a variable using the let keyword:

1
2
let name = 'Benny';
name = 'Sofia';

TS2613

error TS2613: Module ‘add‘ has no default export. Did you mean to use ‘import { add } from "add"‘ instead?

Broken Code ❌

add.ts
1
2
3
export function add(a: number, b: number): number {
return a + b;
}
main.ts
1
2
3
import add from './add';

console.log(add(1000, 337));

Fixed Code ✔️

To fix the bug we have to convert our named export into a default export:

add.ts
1
2
3
export default function add(a: number, b: number): number {
return a + b;
}

TS2616

error TS2616: ‘React’ can only be imported by using ‘import React = require(“react”)’ or a default import.

Broken Code ❌

1
2
3
4
5
import {React, FC} from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

Fixed Code ✔️

Use default import for React:

1
2
3
4
5
import React, {FC} from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

TS2654

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

Broken Code ❌

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

Fix

Video Tutorial


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.

Broken 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/

Broken 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

Broken 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 {}

TS2680

error TS2680: A ‘this’ parameter must be the first parameter.

Broken Code ❌

1
2
3
4
5
6
7
type Person = {
name: string;
}

export function sayHello(text: string = 'Hello', this: Person): void {
console.log(`${text} ${this.name}`)
}

Fixed Code ✔️

TypeScript requires that a this parameter always comes first in the list of parameters:

1
2
3
4
5
6
7
type Person = {
name: string;
}

export function sayHello(this: Person, text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

TS2683

error TS2683: ‘this’ implicitly has type ‘any’ because it does not have a type annotation.

Broken Code ❌

1
2
3
export function sayHello(text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

Fixed Code ✔️

This bug is also a consequence of TS2680. To fix the bug we have to define the context of our function. It can be done by defining this as the first parameter in our argument list and giving it a type annotation:

1
2
3
4
5
6
7
type Person = {
name: string;
}

export function sayHello(this: Person, text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

TS2684

error TS2684: The ‘this’ context of type ‘void’ is not assignable to method’s ‘this’ of type ‘Person’.

Broken Code ❌

1
2
3
4
5
6
7
8
9
type Person = {
name: string;
}

export function sayHello(this: Person, text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

sayHello('Welcome');

Fixed Code ✔️

When calling a function that defines a this parameter, then we have to set the this context with apply, bind or call.

Using apply:

1
2
3
4
5
6
7
8
9
10
11
12
13
type Person = {
name: string;
}

export function sayHello(this: Person, text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

const benny: Person = {
name: 'Benny'
};

sayHello.apply(benny, ['Welcome']);

Using bind:

1
2
3
4
5
6
7
8
9
10
11
12
13
type Person = {
name: string;
}

export function sayHello(this: Person, text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

const benny: Person = {
name: 'Benny'
};

sayHello.bind(benny)('Welcome');

Using call:

1
2
3
4
5
6
7
8
9
10
11
12
13
type Person = {
name: string;
}

export function sayHello(this: Person, text: string = 'Hello'): void {
console.log(`${text} ${this.name}`);
}

const benny: Person = {
name: 'Benny'
};

sayHello.call(benny, 'Welcome');

TS2686

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

Broken 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.

Broken Code ❌

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

Fixed Code ✔️

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

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

Broken Code ❌

1
2
3
4
5
import {FC} from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

Fixed Code ✔️

Use default import for React:

1
2
3
4
5
import React from 'react';

const App: React.FC = (): JSX.Element => {
return <></>;
};

TS2689

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

Broken 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!";
}
}

TS2691

error TS2691: An import path cannot end with a ‘.d.ts’ extension. Consider importing ‘./index’ instead.

Broken Code ❌

You cannot directly import code from declaration files:

1
import { myFunction } from './index.d.ts';

Fixed Code ✔️

You have to import functions from the source code file (e.g. index.ts):

1
import { myFunction } from './index';

TS2693

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

Broken 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

TS2695

error TS2695: Left side of comma operator is unused and has no side effects.

Broken Code ❌

1
2
3
4
5
6
7
8
import express from 'express';

const app = express();

app.use((, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});

Fixed Code ✔️

You just cannot leave out a callback parameter if you don’t want to use it. Mark it with an underscore (_) instead:

1
2
3
4
5
6
7
8
import express from 'express';

const app = express();

app.use((_, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});

TS2715

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

Broken 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’.

Broken 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 Tutorial


TS2730

error TS2730: An arrow function cannot have a ‘this’ parameter.

Broken Code ❌

1
2
3
const loadInitialData = (this: Highcharts.Chart): void => {
// ...
}

Fixed Code ✔️

1
2
3
function loadInitialData(this: Highcharts.Chart): void {
// ...
}

TS2732

error TS2732: Cannot find module ‘../../package.json’. Consider using ‘–resolveJsonModule’ to import module with ‘.json’ extension.

Broken Code ❌

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

Fixed Code ✔️

To fix the issue and allow importing JSON files, you have to set “resolveJsonModule” to true in your “tsconfig.json” file.


TS2739

error TS2739: Type ‘{}‘ is missing the following properties from type ‘Person‘: age, name

Broken Code ❌

1
2
3
4
5
6
type Person = {
age: number;
name: string;
}

const benny: Person = {};

Fixed Code ✔️

The object doesn’t have any properties, so it cannot be assigned to the type of Person. We have to add the missing properties to fix this error:

1
2
3
4
5
6
7
8
9
type Person = {
age: number;
name: string;
}

const benny: Person = {
age: 34,
name: 'Benny'
};

Video Tutorial


TS2741

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

Broken 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 Tutorial


TS2769

error TS2769: No overload matches this call.

Broken Code ❌

1
2
3
4
5
6
7
8
9
10
function sum(a: number, b: number): number;
function sum(a: string, b: string): string;
function sum(a: number | string, b: number | string): number | string {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
return `${parseInt(a + '', 10) + parseInt(b + '', 10)}`;
}

const result = sum('1000', 337);

Fixed Code ✔️

There are only two function overloads for sum. The first overload expects a and b to be of type number. The second overload expects a and b to be of type string but there is no overload that specifies a to be a string while b is a number. We have to add a third overload to allow such function calls:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Function Overload Signature 1
function sum(a: number, b: number): number;
// Function Overload Signature 2
function sum(a: string, b: string): string;
// Function Overload Signature 3
function sum(a: string, b: number): string;
function sum(a: number | string, b: number | string): number | string {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
return `${parseInt(a + '', 10) + parseInt(b + '', 10)}`;
}

const result = sum('1000', 337);

An even easier solution would be to remove all function overloads as the function body allows us to use number or string through the union type of number | string:

1
2
3
4
5
6
7
8
function sum(a: number | string, b: number | string): number | string {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
return `${parseInt(a + '', 10) + parseInt(b + '', 10)}`;
}

const result = sum('1000', 337);

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.

Broken 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

Broken 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

Broken 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‘.

Broken 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}

TS4025

error TS4025: Exported variable ‘App’ has or is using private name ‘FC’.

Broken Code ❌

1
2
3
4
5
import React from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

Fixed Code ✔️

1
2
3
4
5
import React, {FC} from 'react';

const App: FC = (): JSX.Element => {
return <></>;
};

TS4063

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

Broken 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’.

Broken 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;

// ...
}

TS4112

error TS4112: This member cannot have an ‘override’ modifier because its containing class does not extend another class.

Broken Code ❌

1
2
3
4
5
class Cat {
override makeNoise(): string {
return 'Meow!';
}
}

Fixed Code ✔️

1
2
3
4
5
class Cat {
makeNoise(): string {
return 'Meow!';
}
}

TS4113

error TS4113: This member cannot have an ‘override‘ modifier because it is not declared in the base class ‘MyBaseClass‘.

Broken Code ❌

1
2
3
4
5
6
7
8
9
10
11
class MyBaseClass {
sayHello(): string {
return 'Hello!';
}
}

class MyDerivedClass extends MyBaseClass {
override sayWelcome(): string {
return 'Welcome!';
}
}

Fixed Code ✔️

You can only override functions in our derived class when those exist in our base class. We can solve the error by overwriting an existing function:

1
2
3
4
5
6
7
8
9
10
11
class MyBaseClass {
sayHello(): string {
return 'Hello!';
}
}

class MyDerivedClass extends MyBaseClass {
override sayHello(): string {
return 'Welcome!';
}
}

Depending on our use case, we can also remove the override modifier:

1
2
3
4
5
6
7
8
9
10
11
class MyBaseClass {
sayHello(): string {
return 'Hello!';
}
}

class MyDerivedClass extends MyBaseClass {
sayWelcome(): string {
return 'Welcome!';
}
}

TS4114

error TS4114: This member must have an ‘override‘ modifier because it overrides a member in the base class ‘MyBaseClass‘.

Broken Code ❌

1
2
3
4
5
6
7
8
9
10
11
class MyBaseClass {
sayHello(): string {
return 'Hello!';
}
}

class MyDerivedClass extends MyBaseClass {
sayHello(): string {
return 'Welcome!';
}
}

Fixed Code ✔️

The error pops up when “noImplicitOverride” is set to true in your “tsconfig.json” file, and you don’t use the override modifier when overwriting a function from your base class. You can fix this by setting “noImplicitOverride” to false (not recommended) or using the override modifier (preferred solution):

1
2
3
4
5
6
7
8
9
10
11
class MyBaseClass {
sayHello(): string {
return 'Hello!';
}
}

class MyDerivedClass extends MyBaseClass {
override sayHello(): string {
return 'Welcome!';
}
}

TS5025

error TS5025: Unknown compiler option ‘–no-emit’. Did you mean ‘noEmit’?

Broken Code ❌

1
tsc --no-emit

Fixed Code ✔️

Use camel case writing:

1
tsc --noEmit

TS5055

error TS5055: Cannot write file because it would overwrite input file. Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files.

Broken Code ❌

1
tsc mycode.js --allowJs

Fixed Code ✔️

1
tsc mycode.js --allowJs --outDir dist

Alternatively, you can also skip compiling code (if you just want to check the types of your code):

1
tsc mycode.js --allowJs --noEmit

TS6053

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

Broken 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.

Broken Code ❌

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

Fixed Code ✔️

When using require then we can access files outside the specified root folder for input files (“rootDir” in “tsconfig.json”):

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

TS6133

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

Broken 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 Tutorial


TS6196

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

Broken 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;
}

TS6198

error TS6198: All destructured elements are unused.

Broken Code ❌

1
2
3
4
5
6
7
8
function returnSomething(): {low: number, high: number} {
return {
low: 10,
high: 20,
};
}

const {low: lowest, high: highest} = returnSomething();

Fixed Code ✔️

You have to make use of the destructured values in your application / code:

1
2
3
4
5
6
7
8
9
10
function returnSomething(): {low: number, high: number} {
return {
low: 10,
high: 20,
};
}

const {low: lowest, high: highest} = returnSomething();

console.log(lowest + highest);

TS6504

error TS6504: File ‘plain_js.js’ is a JavaScript file. Did you mean to enable the ‘allowJs’ option?

Broken Code ❌

1
tsc mycode.js

Fixed Code ✔️

1
tsc mycode.js --allowJs

TS7006

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

Broken Code ❌

main.ts
1
2
3
function greeter(person) {
return `Hello, ${person}`;
}
tsconfig.json
1
2
3
4
5
{
"compilerOptions": {
"noImplicitAny": true
}
}

Fixed Code ✔️

You have to define the type for the argument named person:

main.ts
1
2
3
function greeter(person: string) {
return `Hello, ${person}`;
}

Alternative, but not recommend:


TS7016

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

Broken Code ❌

1
import UUID = require('uuidjs');

Fixed Code ✔️

The problem shows that uuidjs is a plain JavaScript module and doesn’t ship with TypeScript declaration files (.d.ts). That’s why we have to use the CommonJS import syntax to import this module in a Node.js project:

main.ts
1
const UUID = require('uuidjs');

A proper fix would be to have a uuidjs.d.ts as part of uuidjs: https://github.com/LiosK/UUID.js/issues/6

Example:

uuidjs.d.ts
1
2
3
declare class UUID {
static generate(): string;
}
main.ts
1
2
import UUID from 'uuidjs';
const id = UUID.generate();

TS7017

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

Broken Code ❌

1
const recipients = {};

Fixed Code ✔️

You have to define the type for indexing your object properties (object["index"]):

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

The name of the index can be freely chosen:

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

How to fix such errors in interfaces:

1
2
3
interface Recipients {
[index: string]: number;
}

Alternative, but not recommend:

error TS7017: Element implicitly has an ‘any‘ type because type ‘typeof globalThis‘ has no index signature.

Broken Code ❌

1
global.client = new APIClient(APIClient.URL_DEMO, 'global-demo-api-key');

Fixed Code ✔️

1
2
3
4
5
declare global {
var client: APIClient;
}

global.client = new APIClient(APIClient.URL_DEMO, 'global-demo-api-key');

TS7027

error TS7027: Unreachable code detected.

Broken Code ❌

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

Fixed Code ✔️

Your code cannot print text to the standard output when your program is told to exit beforehand, so you have to remove the call to exit or place it at a later point in time:

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

TS7030

error TS7030: Not all code paths return a value.

Broken Code ❌

1
2
3
4
5
function getFlightType(type: 1 | 2) {
if (type === 1) {
return 'Return trip';
}
}

Fixed Code ✔️

TypeScript reminds us that we forgot to return a value in case our if-condition doesn’t match. We can solve this problem in many ways.

Always return a value:

1
2
3
4
5
6
function getFlightType(type: 1 | 2) {
if (type === 1) {
return 'Return trip';
}
return 'One way';
}

Add general else:

1
2
3
4
5
6
7
function getFlightType(type: 1 | 2) {
if (type === 1) {
return 'Return trip';
} else {
return 'One way';
}
}

Handle all cases:

1
2
3
4
5
6
7
8
function getFlightType(type: 1 | 2) {
switch (type) {
case 1:
return 'Return trip';
case 2:
return 'One way';
}
}

Add default case:

1
2
3
4
5
6
7
8
function getFlightType(type: 1 | 2) {
switch (type) {
case 1:
return 'Return trip';
default:
return 'One way';
}
}

Define that the return type can be void:

1
2
3
4
5
function getFlightType(type: 1 | 2): string | void {
if (type === 1) {
return 'Return trip';
}
}

Video Tutorial


TS7031

error TS7031: Binding element ‘age’ implicitly has an ‘any’ type.

Broken Code ❌

1
2
3
export function printAge({age}): void {
console.log(age);
}

Fixed Code ✔️

TypeScript complains because it doesn’t know the type of the argument that we are destructuring. That’s why it sets all
its properties to the type of any. To prevent that we have to define a type for the parameter of the printAge
function:

1
2
3
4
5
6
7
8
type Person = {
age: number;
name: string;
}

export function printAge({age}: Person): void {
console.log(age);
}

TS7034

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

Broken Code ❌

1
const expectations = [];

Fixed Code ✔️

An array can collect values of different types, so we have to tell TypeScript which types we want to collect:

1
const expectations: string[] = [];

If we want to specify multiple types, we have to define a union type:

1
2
3
const expectations: (string | number)[] = [];
expectations.push('1');
expectations.push(2);

Alternative:

1
2
3
4
type ArrayInput = string | number;
const expectations: ArrayInput[] = [];
expectations.push('1');
expectations.push(2);

Unrecommended solutions:


TS7041

error TS7041: The containing arrow function captures the global value of ‘this‘.

Broken Code ❌

1
2
3
4
5
6
const myObject = {
name: 'Benny',
myMethod: () => {
return this.name;
}
};

Fixed Code ✔️

We have to replace our arrow function with an anonymous function declaration to prevent that our this context gets captured:

1
2
3
4
5
6
const myObject = {
name: 'Benny',
myMethod: function() {
return this.name;
}
};

Since ECMAScript 2015 (ES6) this can be shortened (Object Literal Property Value Shorthand) to:

1
2
3
4
5
6
const myObject = {
name: 'Benny',
myMethod() {
return this.name;
}
};

TS7053

error TS7053: Element implicitly has an ‘any‘ type because expression of type ‘string‘ can’t be used to index type ‘Person‘. No index signature with a parameter of type ‘string‘ was found on type ‘Person‘.

Broken Code ❌

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

function getValue(person: Person, key: string): string {
return person[key];
}

Fixed Code ✔️

There are multiple ways to solve the error. You can define an index signature for the Person interface which will allow all strings:

1
2
3
4
5
6
7
8
interface Person {
[index: string]: string;
name: string;
}

function getValue(person: Person, key: string): string {
return person[key];
}

However, this is not recommend as it will allow you to access keys that are not defined (like age):

1
2
3
4
5
6
7
8
9
10
interface Person {
[index: string]: string;
name: string;
}

function getValue(person: Person, key: string): string {
return person[key];
}

console.log(getValue({name: 'Benny'}, 'age')); // returns `undefined`

The better solution is using the keyof type operator which creates a literal union of its keys:

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

function getValue(person: Person, key: keyof Person): string {
return person[key];
}

TS8020

error TS8020: JSDoc types can only be used inside documentation comments.

Broken Code ❌

1
2
3
function add(a: number, b: number, c: number?): number {
return a + b;
}

Fixed Code ✔️

If you wanted to make c optional:

1
2
3
function add(a: number, b: number, c?: number): number {
return a + b;
}

If you wanted to document c with JSDoc:

1
2
3
4
5
6
7
8
/**
* @param a Initial quantity
* @param b Amount to add
* @param [c] Optional number to add
*/
function add(a: number, b: number, c: number): number {
return a + b;
}