Discover the solution to your TypeScript problems with our comprehensive list of common TypeScript errors. Each entry includes the faulty code and its fixed version, ensuring you can quickly resolve any issue and get back to coding.
If you’re interested in more TypeScript troubleshooting and best practices, check out our free TypeScript tutorials on YouTube. 📺 You can also follow TypeScript TV on Twitter to stay up to date. 🐤
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 3
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.';
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
typePerson { age: number; name: string; }
Fixed Code ✔️
You need to assign your type declaration using the = character:
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' />
TS1015
error TS1015: Parameter cannot have question mark and initializer.
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”:
error TS1036: Statements are not allowed in ambient contexts.
Broken Code ❌
1 2 3 4 5
import {APIClient} from'../../APIClient';
declareglobal { 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
declareglobal { functionclient(): APIClient; }
If you don’t want client to be a function, you have to use thevar` keyword:
1 2 3
declareglobal { varclient: APIClient; }
TS1038
error TS1038: A ‘declare’ modifier cannot be used in an already ambient context.
Broken Code ❌
1 2 3
declareglobal { declarevarREST_URL: string; }
Fixed Code ✔️
1 2 3
declareglobal { varREST_URL: string; }
TS1039
error TS1039: Initializers are not allowed in ambient contexts.
Broken Code ❌
index.d.ts
1 2 3 4 5
declaremodule hexo { var config = {
} }
Fixed Code ✔️
Within a declaration file (ambient context), you should define types instead of implementing code. Consequently, you’ll need to replace the initialization with a type annotation:
index.d.ts
1 2 3
declaremodule hexo { varconfig: {}; }
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
constMAGIC_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
exportconstMAGIC_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.
error TS1070: ‘private’ modifier cannot appear on a type member.
Broken Code ❌
1 2 3
interfaceAnimal { privatename: 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
interfaceAnimal { name: string; }
Video Tutorial
TS1095
error TS1095: A ‘set’ accessor cannot have a return type annotation.
forawait (const line of rl) { console.log(line); } }
TS1109
error TS1109: Expression expected.
Broken Code ❌
1
const lastName = thrownewError('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) { thrownewError('Missing last name'); }
TS1117
error TS1117: An object literal cannot have multiple properties with the same name in strict mode.
error TS1155: ‘const’ declarations must be initialized.
Broken Code ❌
1
constname: string;
Fixed Code ✔️
1
constname: string = 'Benny';
Alternatively you can define a block-scoped local variable:
1
letname: 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.`;
TS1183
error TS1183: An implementation cannot be declared in ambient contexts.
You cannot write a function implementation inside a declaration file (*.d.ts). You can only declare its signature:
index.d.ts
1
exportfunctionlogSomething(error: unknown): void;
Alternatively, you can write your function implementation inside a source code file (*.ts).
TS1192
error TS1192: Module ‘json5‘ has no default export.
Broken Code ❌
1
import json5 from'json5';
Fixed Code ✔️
When you are importing a module with built-in TypeScript declarations and TypeScript tells you that this module does not have a default export, then you can solve this problem by adding “allowSyntheticDefaultImports” to your “tsconfig.json” file and setting it to true:
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.
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:
error TS1218: Export assignment is not supported when ‘–module’ flag is ‘system’.
Broken Code ❌
1 2 3 4 5
classLRUCache { // ... }
export = LRUCache;
Fixed Code ✔️
1 2 3
exportclassLRUCache { // ... }
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.
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.
The type Range is being used to declare the return type of static function Ranger.getFullRange but later on it is also being used to create an instance using new Range. When you want to use a type to construct instances (or do anything else beyond declaring types), then you have to use the import statement instead of import type:
1 2 3 4 5 6 7 8 9 10
importtype { TextEditor } from'vscode'; import { Range } from'vscode';
With type-only imports and exports you cannot use a default import together with a named import in one single line of code. The TypeScript team chose this limitation to avoid ambiguity. You will have to use separate import statements:
When “importsNotUsedAsValues” is set to “error” in your “tsconfig.json”, then you have to use the “import type” syntax when you just want to refer to a type instead of using it as a value:
You can also set “importsNotUsedAsValues” to “preserve” which is not recommended.
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.
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.
error TS1385: Function type notation must be parenthesized when used in a union type.
Broken Code ❌
1
typeMyCallback = () =>number | () =>string
Fixed Code ✔️
When using a union type, you have to put additional function types in parentheses:
1
typeMyCallback = () =>number | (() =>string);
TS1389
error TS1389: ‘this’ is not allowed as a variable declaration name.
Broken Code ❌
1
constthis = 'something';
Fixed Code ✔️
The name this cannot be used to declare a variable because it is already a reserved keyword to refer to the current object in a method or constructor.
That’s why you have to choose a different name:
1
const that = 'something';
TS1431
error TS1431: ‘for await’ loops 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.
forawait (const line of rl) { console.log(line); }
TS1432
error TS1432: Top-level ‘for await’ loops are only allowed when the ‘module’ option is set to ‘es2022’, ‘esnext’, ‘system’, ‘node16’, or ‘nodenext’, and the ‘target’ option is set to ‘es2017’ or higher.
TS1471: Module ‘@headlessui/react‘ cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.
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):
constApp: FC = (): JSX.Element => { return<></>; };
Fixed Code ✔️
1 2 3 4 5
importReact, {FC} from'react';
constApp: FC = (): JSX.Element => { return<></>; };
TS2305
error TS2305: Module ‘./sum‘ has no exported member ‘multiply‘.
Broken Code ❌
sum.ts
1 2 3
exportfunctionsum(a: number, b: number): number { return a + b; }
main.ts
1 2 3
import { multiply } from'./sum';
console.log(multiply(1, 2));
Fixed Code ✔️
The file “sum.ts” exports a function named “sum”, so we have to fix the named import in our “main.ts” file:
main.ts
1 2 3
import { sum } from'./sum';
console.log(sum(1, 2));
TS2306
error TS2306: File ‘add.ts‘ is not a module.
Broken Code ❌
add.ts
1 2 3
functionadd(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
exportfunctionadd(a: number, b: number): number { return a + b; }
Alternatively we can use a default export:
add.ts
1 2 3
exportdefaultfunctionadd(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));
Video Tutorial
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:
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:
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:
TS2339: Property ‘pop‘ does not exist on type ‘readonly [1, 2, 3]‘.
Broken Code ❌
1 2
const array = [1, 2, 3] asconst; array.pop();
When using a const assertion on an array, then your array becomes readonly (immutable), so you cannot modify its elements using in-place operations such as pop. You will have to make your array mutable:
1 2
constarray: number[] = [1, 2, 3]; array.pop();
TS2344
error TS2344: Type ‘{ name: string; }‘ does not satisfy the constraint ‘{ age: number; }‘. Property ‘age‘ is missing in type ‘{ name: string; }‘ but required in type ‘{ age: number; }‘.
Broken Code ❌
1 2 3 4 5 6
function increaseAge<T extends { age: number }>(data: T): T { data.age += 1; return data; }
As an alternative, type argument inference can be used:
1 2 3 4 5 6
function increaseAge<T extends { age: number }>(data: T): T { data.age += 1; return data; }
increaseAge({age: 25, name: 'Benny'});
TS2345
error TS2345: Argument of type ‘number‘ is not assignable to parameter of type ‘TimerHandler‘.
Broken Code ❌
1 2 3 4 5
functionadd(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
functionadd(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 = newBaseN([1, 2, 3], 2);
TS2349
error TS2349: Cannot invoke an expression whose type lacks a call signature. Type ‘Promise‘ has no compatible call signatures.
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.
The constructor implementation is missing curly brackets which is why TypeScript does not recognize the constructor implementation and files error TS2369. To solve it you have to add the missing curly brackets:
error TS2370: A rest parameter must be of an array type.
Broken Code ❌
1 2 3 4 5
functionsum(...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
functionsum(...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
functionadd(a: number, b: number, c: number = 0): number; functionadd(a: number | string, b: number | string, c: number | string = 0): number { returnparseInt(`${a}`, 10) + parseInt(`${b}`, 10); }
Fixed Code ✔️
Remove parameter initializer from function overload:
1 2 3 4
functionadd(a: number, b: number, c: number): number; functionadd(a: number | string, b: number | string, c: number | string = 0): number { returnparseInt(`${a}`, 10) + parseInt(`${b}`, 10); }
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:
error TS2403: TS2403: Subsequent variable declarations must have the same type. Variable ‘window‘ must be of type ‘Window & typeof globalThis‘, but here has type ‘any‘.
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:
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.
The address in Exchange is a mandatory property but in StockExchange it is declared as being optional which creates an incompatibility in the type. To fix the error, the property address has either to become optional or mandatory in both declarations:
You cannot redeclare a module that you are importing, but you can outsource your additional typings to a declaration file in order to apply declaration merging:
Depending on the configuration of “lib” in your “tsconfig.json” file, there might be global variables that are present (like window when using the “dom” library provided by TypeScript). In this case you cannot redeclare the global variable and have to choose another name:
1
const myWindow = 'blue';
TS2454
error TS2454: Variable ‘myFavoriteNumber’ is used before being assigned.
Broken Code ❌
1 2 3 4
exportfunctionmyNumber(): number { letmyFavoriteNumber: number; return myFavoriteNumber; }
exportfunctionmyNumber(): number { letmyFavoriteNumber: number = 72; return myFavoriteNumber; }
TS2456
error TS2456: Type alias ‘MyValue‘ circularly references itself.
Broken Code ❌
1
typeMyValue = number | string | Record<string, MyValue>;
Fixed Code ✔️
When defining a recursive type, you have to use the object syntax:
1
typeMyValue = number | string | {[key: string]: MyValue};
TS2459
error TS2459: Module ‘./myFunction‘ declares ‘myFunction‘ locally, but it is not exported.
Broken Code ❌
myFunction.ts
1 2 3 4 5
functionmyFunction(a: number, b: number): number { return a + b; }
export {}
index.ts
1 2 3
import {myFunction} from'./myFunction';
myFunction(1, 2);
Fixed Code ✔️
When you want to import your function in another file, you have to make sure that it is exported using the export keyword:
myFunction.ts
1 2 3
exportfunctionmyFunction(a: number, b: number): number { return a + b; }
index.ts
1 2 3
import {myFunction} from'./myFunction';
myFunction(1, 2);
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.
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:
If you want to access enums by indices, you must remove the const keyword and values from your enum:
1 2 3 4 5 6
enumOrderSide { BUY, SELL, }
console.log(OrderSide[0]);
⚠️ Be aware that this may become unsafe as you may unintentionally access indices that are not defined.
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:
TypeScript warns us that person can be undefined (because of the ?). There are multiple ways to fix the problem. We can do an existence check using an if-condition:
1 2 3 4 5 6 7 8 9
typePerson = { age: number; };
functionlogAge(person?: Person): void { if (person) { console.log(person.age); } }
Optional chaining is less preferable in this case as it will log undefined if the person is undefined. Using the if-condition from the solution above, nothing will be logged to the console in case the person is undefined.
TS2533
error TS2533: Object is possibly ‘null’ or ‘undefined’.
The error originates from the fact that address can be undefined (because of the ?) or null. To fix the problem, we can check if address is defined by using optional chaining:
error TS2550: Property ‘setPrototypeOf‘ does not exist on type ‘ObjectConstructor‘. Do you need to change your target library? Try changing the ‘lib’ compiler option to ‘es2015’ or later.
The problem occurs with weak types (in this case User). All properties of a weak type are optional but when your input doesn’t match any of the properties, you will get to see error TS2559. To fix it you have to match at least one of the optional properties:
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
classDog { privatename: string; }
Fixed Code ✔️
We have to initialize the name member either at its definition or within the constructor.
error TS2567: Enum declarations can only merge with namespace or other enum declarations. lib.dom.d.ts(18299, 6): ‘ResponseType’ was also declared here.
Broken Code ❌
1 2 3 4
enumResponseType { ACTIVE, ERROR, }
Fixed Code ✔️
In the broken code shown above, a type ResponseType is already declared as part of the “dom” typings. Enums can be merged with other enums but since the other declaration of ResponseType is a type, we cannot merge the existing declaration with our custom one. That’s why we have to remove “dom” from the “lib” entries in our “tsconfig.json” file or use a different name for our enum:
1 2 3 4
enumMyResponseType { ACTIVE, ERROR, }
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:
If your variable is of type unknown, then you can use a type guard to narrow the type of your variable. If you want to be sure that you have an object at hand, you can use the typeof type guard:
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.
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:
error TS2583: Cannot find name ‘BigInt’. Do you need to change your target library? Try changing the ‘lib’ compiler option to ‘es2020’ or later.
Broken Code ❌
tsconfig.json
1 2 3 4 5 6 7
{ "compilerOptions":{ "lib":[ "dom" ] } }
ImmortalPerson.ts
1 2 3
typeImmortalPerson = { age: BigInt; }
Fixed Code ✔️
Arbitrary-precision integers (BigInt) were introduced in 11th edition of the ECMAScript Language Specification (ES11 / ES2020), so you have to add this information to the “lib” property of your TypeScript configuration to make use of this API:
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';
TS2595
error TS2595: ‘React‘ can only be imported by using a default import.
Broken Code ❌
1
import {React} from'react';
Fixed Code ✔️
A default import cannot be put in curly braces:
1
importReactfrom'react';
TS2611
error TS2611: ‘name‘ is defined as a property in class ‘Person‘, but is overridden here in ‘MyPerson‘ as an accessor.
Getters and setters are property accessors, so you have to make sure that you don’t mix property definitions with property accessor definitions. Using the accessor keyword, you can turn a property into a property accessor:
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
exportfunctionadd(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
exportdefaultfunctionadd(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';
constApp: FC = (): JSX.Element => { return<></>; };
Fixed Code ✔️
Use default import for React:
1 2 3 4 5
importReact, {FC} from'react';
constApp: FC = (): JSX.Element => { return<></>; };
TS2652
error TS2652: Merged declaration ‘MyPerson‘ cannot include a default export declaration. Consider adding a separate ‘export default MyPerson‘ declaration instead.
Broken Code ❌
1 2 3 4 5
constMyPerson = 'Benny';
exportdefaultfunctionMyPerson() { // }
Fixed Code ✔️
You cannot use the same name to declare a constant and a function. If your intention is to export your constant, then do the following:
1 2 3
constMyPerson = 'Benny';
exportdefaultMyPerson;
TS2654
error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.
Remove /// <reference path="..." /> in .d.ts files
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 ❌
proteus.d.ts
1 2
declaremoduleProteus { }
Fixed Code ✔️
proteus.d.ts
1 2
exportmoduleProteus { }
TS2661
error TS2661: Cannot export ‘getSdk‘. Only local declarations can be exported from a module.
Broken Code ❌
index.ts
1
export {getSdk};
getSdk.ts
1
functiongetSdk() {}
Fixed Code ✔️
If you want to re-export getSdk in another file, you have to export it first from its origin and then import it in the file where you want to re-export it:
index.ts
1 2 3
import {getSdk} from'./getSdk';
export {getSdk};
getSdk.ts
1
exportfunctiongetSdk() {}
TS2663
error TS2663: Cannot find name ‘firstName‘. Did you mean the instance member ‘this.firstName‘?
Starting from TypeScript 4.9, you can also use an auto-accessor field:
1 2 3
classPerson { accessor firstName: string = ''; }
TS2664
error TS2664: Invalid module name in augmentation, module ‘gas-local‘ cannot be found.
Broken Code ❌
main.ts
1
declaremodule"gas-local";
Fixed Code ✔️
The problem occurs when you want to write a module augmentation for a package that isn’t found in your “node_modules” directory. Make sure to install the module:
1
npm install gas-local --save
TS2665
error TS2665: Invalid module name in augmentation. Module ‘gas-local‘ resolves to an untyped module at ‘../node_modules/gas-local/index.js‘, which cannot be augmented.
Broken Code ❌
main.ts
1 2 3 4
declaremodule"gas-local"; import gas from'gas-local';
const glib = gas.require('./src');
Fixed Code ✔️
You have to move the shorthand ambient module declaration from a “.ts” file into a “.d.ts” file:
types.d.ts
1
declaremodule"gas-local";
main.ts
1 2 3
import gas from'gas-local';
const glib = gas.require('./src');
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.
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.
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:
error TS2677: A type predicate’s type must be assignable to its parameter’s type. Type ‘number‘ is not assignable to type ‘string‘.
Broken Code ❌
1 2 3
const isInteger = (input: string): input is number => { return !!parseInt(input, 10); };
Fixed Code ✔️
The input is declared to be of type string which is why the type predicate cannot turn it into a number because these two declarations are mutually exclusive. That’s why we have to declare an input type of any:
1 2 3
const isInteger = (input: any): input is number => { return !!parseInt(input, 10); };
TS2678
error TS2678: Type ‘StreamStatus‘ is not comparable to type ‘number‘.
functionhandleResponse(response: StreamResponse): void { switch (response.status) { caseStreamStatus.ONLINE: console.log('You are online.'); break; caseStreamStatus.OFFLINE: console.log('You are offline.'); break; } }
Fixed Code ✔️
The StreamResponse declares a “status” property of type number but the switch-case statement checks against StreamStatus, so we have to adjust the typing for “status” of StreamResponse:
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:
In the error above, a Response is declared which should be merged (using declaration merging) with the Response interface of the “dom” library which is set in “lib” within the “tsconfig.json” file. When merging with an existing declaration, the property types of the first declaration must be matched because you can only add additional properties when using declaration merging. The same rules applies to modifiers. Because “status” has a readonly modifier in the existing Response interface, we must declare the same in our own interface extension:
error TS2689: Cannot extend an interface ‘Animal’. Did you mean ‘implements’?
Broken Code ❌
1 2 3 4 5 6 7
interfaceAnimal { name: string; }
classDogextendsAnimal { 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.
The generic type Key is defined with a default value of string which makes this type parameter not optional. However, the Value type parameter is optional and optional parameters are not allowed to follow required parameters.
To solve the situation, we have can switch the position of the two parameters which would impact how we use the 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:
Usually the error TS2717 shows up when you have multiple versions of typings (i.e. @types/react) for the same interfaces in your codebase. If you run into these kind of problems, you can inspect your typing resolutions using yarn why (i.e. yarn why @types/react) or npm explain (i.e. npm explain @types/react) to find out where you have conflicting typings.
Video Tutorial
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‘.
Method invocation only works if the method is defined. The onClick method of the event object in the example above is optional, which means it can be undefined. That’s why we have to make an existence check before calling / invoking it:
error TS2740: Type ‘TextLine‘ is missing the following properties from type ‘Position‘: line, character, isBefore, isBeforeOrEqual, and 6 more.
Broken Code ❌
1 2 3 4 5
import {Position, TextEditor} from'vscode';
functionlogPosition(textEditor: TextEditor, startLine: Position = textEditor.document.lineAt(0)) { console.log(startLine.line); }
Fixed Code ✔️
The parameter startLine is requiring a value of type Position but the default value returns a value of type TextLine, so this has to be fixed to return the expected type:
1 2 3 4 5
import {Position, TextEditor} from'vscode';
functionlogPosition(textEditor: TextEditor, startLine: Position = textEditor.document.lineAt(0).range.start) { console.log(startLine.line); }
TS2741
error TS2741: Property ‘name’ is missing in type ‘{}’ but required in type ‘Animal’.
Broken Code ❌
1 2 3 4 5
interfaceAnimal { name: string; }
constlaika: 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
interfaceAnimal { name: string; }
constlaika: Animal = { name: 'Laika', };
Video Tutorial
TS2742
error TS2742: The inferred type of ‘ProductDeleteDocument‘ cannot be named without a reference to ‘graphql-tag/node_modules/graphql/language/ast‘. This is likely not portable. A type annotation is necessary.
In a monorepository the error TS2742 can show up when you are using a package that has not set a “main” property in its “package.json” file. Sometimes it also happens that there is a “types” property which does not point to the correct typings. Make sure both paths are present and relative:
You can run into this error when a code generator, such as graphql-code-generator, misses to render an important statement (see here). This can happen when the generator relies on implicit typings (type inference) and it can be fixed by instructing your code generator to render the missing import statement. Depending on your code generator this could be done through a config file:
1 2 3 4 5 6
plugins: -add: content:'import type { DocumentNode } from "graphql/language/ast";' -typescript -typescript-operations -typescript-react-apollo
TS2749
error TS2749: ‘paramNames‘ refers to a value, but is being used as a type here. Did you mean ‘typeof paramNames‘?
functionsum(a: number, b: number): number; functionsum(a: string, b: string): string; functionsum(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 functionsum(a: number, b: number): number; // Function Overload Signature 2 functionsum(a: string, b: string): string; // Function Overload Signature 3 functionsum(a: string, b: number): string; functionsum(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
functionsum(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);
TS2774
error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
Usually the problem derives from a mismatch in @types/react. When you have libraries that are dependent on a specific version of @types/react (i.e. v17.0.47) and you have other libraries working with another major version of @types/react (i.e. v18.0.14), then this can cause compatibility issues when using React.ReactNode or JSX.Element. You have to streamline your dependencies on @types/react, so that these follow the same major version.
You can find all libraries depending on @types/react in your project by executing npm explain @types/react (when a package-lock.json file is present) or yarn why @types/react (when a yarn.lock file is present).
TS2792
error TS2792: Cannot find module ‘@playwright/test‘. Did you mean to set the ‘moduleResolution‘ option to ‘node‘, or to add aliases to the ‘paths‘ option?
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):
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
TS5054
error TS5054: A ‘tsconfig.json’ file is already defined at: ‘C:/dev/bennycode/ts-node-starter/tsconfig.json‘.
Broken Code ❌
1
npx tsc --init
Fixed Code ✔️
You cannot initialize a new TypeScript compiler configuration when there is one already present. You have to delete the existing file first.
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
TS5058
error TS5058: The specified path does not exist: ‘test.json’.
Broken Code ❌
1
npx tsc --project test.json
Fixed Code ✔️
You probably don’t have a TS config named test.json. Try to load tsconfig.json:
1
npx tsc --project tsconfig.json
TS5069
error TS5069: Option ‘declarationMap’ cannot be specified without specifying option ‘declaration’ or option ‘composite’.
Your TS config is extending another config (called base.json) which cannot be found. Make sure that this file (base.json) exists or remove your extends property.
TS5101
error TS5101: Option ‘importsNotUsedAsValues’ is deprecated and will stop functioning in TypeScript 5.5. Specify compilerOption ‘“ignoreDeprecations”: “5.0”‘ to silence this error. Use ‘verbatimModuleSyntax’ instead.
The compiler option importsNotUsedAsValues is not recommended when using TypeScript 5 and above, so you have to remove it from your tsconfig.json file:
tsconfig.json
1 2 3 4
{ "compilerOptions":{ } }
TS6053
error TS6053: File ‘/typings/index.d.ts‘ not found.
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');
An even better solution would be changing the “rootDir” in your “tsconfig.json”, so that it includes the “package.json” file that you are trying to important. This may require you to also set “allowJs” to true in your “tsconfig.json”.
TS6133
error TS6133: ‘volume‘ is declared but its value is never read.
The resolve function of a Promise is not a constructor. You can use the new keyword only with constructors, so the new keyword has to be removed in order to fix the code:
You have to add a return-type annotation and preferably a function implementation:
1 2 3 4 5
namespaceMyModule { exportfunctionsum(a: number, b: number): number { return a + b; } }
TS7016
error TS7016: Could not find a declaration file for module ‘uuidjs‘.
Broken Code ❌
1
importUUID = require('uuidjs');
Fixed Code ✔️
Solution 1
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 environment:
importUUIDfrom'uuidjs'; const id = UUID.generate();
Solution 3
If external typings are available in the DefinitelyTyped repository, then you can also install external declarations from there:
1
npm i --save-dev @types/uuidjs
Solution 4
If there are no declarations available and you want to use the module (in this case uuidjs) with standard import syntax (not CommonJS), then you can create a shorthand ambient module declaration by creating a “*.d.ts” file and writing the following into it:
types.d.ts
1
declaremodule"uuidjs";
Video Tutorial
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
constrecipients: {[index: string]: number} = {};
The name of the index can be freely chosen:
1
constrecipients: {[myKey: string]: number} = {};
How to fix such errors in interfaces:
1 2 3
interfaceRecipients { [index: string]: number; }
Alternative, but not recommend:
Set “noImplicitAny” to false in your “tsconfig.json”
error TS7017: Element implicitly has an ‘any‘ type because type ‘typeof globalThis‘ has no index signature.
error TS7022: ‘window‘ implicitly has type ‘any‘ because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
Broken Code ❌
1
varwindow = window || null;
tsconfig.json
1 2 3 4
{ "compilerOptions":{ "lib":["es2017"] }
Fixed Code ✔️
The above error can occur when TypeScript doesn’t know about the window interface. Make sure to add “dom” to your list of known runtime libraries in your compiler options:
tsconfig.json
1 2 3 4
{ "compilerOptions":{ "lib":["dom","es2017"] }
TS7023
error TS7023: ‘fibonacci‘ implicitly has return type ‘any‘ because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
To avoid the implicit typing of any for the return type, you have to add a return type annotation:
1 2 3
functionfibonacci(n): number { return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2); }
TS7026
error TS7026: JSX element implicitly has type ‘any’ because no interface ‘JSX.IntrinsicElements’ exists.
Broken Code ❌
1 2 3 4 5
functionApp() { return<p>My App!</p>; }
exportdefaultApp;
Fixed Code ✔️
The global JSX namespace is declared in @types/react. You have to install the @types/react package to make use of it:
1
yarn add --dev @types/react
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:
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:
Using this is not allowed in arrow functions (source) because arrow functions aren’t made to work with call, apply and/or bind methods (source). We have to replace our arrow function with an anonymous function declaration to prevent that our this context gets captured:
error TS7044: Parameter ‘a‘ implicitly has an ‘any‘ type, but a better type may be inferred from usage.
Broken Code ❌
1
constmultiply = (a, b) => a * b;
Fixed Code ✔️
From the body of the arrow function expression, TypeScript can see by the * that a and b may be of type number:
1
constmultiply = (a: number, b: number) => a * b;
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‘.
error TS8020: JSDoc types can only be used inside documentation comments.
Broken Code ❌
1 2 3
functionadd(a: number, b: number, c: number?): number { return a + b; }
Fixed Code ✔️
If you wanted to make c optional:
1 2 3
functionadd(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 */ functionadd(a: number, b: number, c: number): number { return a + b; }
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>
TS17004
error TS17004: Cannot use JSX unless the ‘–jsx’ flag is provided.
Broken Code ❌
1 2 3 4 5
functionApp() { return<p>My App!</p>; }
exportdefaultApp;
Fixed Code ✔️
You have to add a configuration for “jsx” to your “tsconfig.json” file:
tsconfig.json
1 2 3 4 5
{ "compilerOptions":{ "jsx":"react" } }
TS17009
error TS17009: ‘super’ must be called before accessing ‘this’ in the constructor of a derived class.
If you want to use the shorthand property name syntax to access the age property, you have to make sure that this variable is defined in the first place:
error TS18016: Private identifiers are not allowed outside class bodies.
Broken Code ❌
1 2 3
interfacePerson { #age: number; }
Fixed Code ✔️
Private properties can only be used in classes but not in interfaces. We therefore need to convert the interface into a class in order to be able to compile the code:
1 2 3
classPerson { #age: number; }
TS80005
error TS80005: ‘require’ call may be converted to an import.