Leverage specialized TypeScript typings with .d.ts files in Next.js (Error: Module cannot be found: Unable to resolve ...)

When using a JavaScript library that lacks @type definitions for TypeScript, I had to create my own .d.ts file named foo.d.ts. The project structure is as follows:

...
.next/
pages/
...
typings/
    foo.d.ts
...
tsconfig.json

In my VS Code editor, the definition works fine and I can import it into my component like so:

import {Foo} from "foo";

However, during runtime I encounter an error in the browser console:

Module not found: Can't resolve 'foo'

I attempted to resolve this issue by adding the following to my tsconfig.json:

"typeRoots": [ "node_modules/@types", "typings" ]

I also tried explicitly including foo.d.ts in the include section alongside next-env.d.ts.

The contents of foo.d.ts are as follows:

declare module 'foo' {
    declare interface ValidationError {
        message?: string;
    }
    declare namespace Foo {
        class Bar {
            constructor(config: any, displayErrorsCallback: (data: ValidationError[]) => void, onSubmitTriggered: () => void);
        }
    }
}

Update (added tsconfig)

{
  "compilerOptions": {
    "target": "es6",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "typeRoots": [
      "node_modules/@types",
      "typings"
    ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

Answer №1

To include your type definition file, simply add .d after the file name. For example, import your type definition as

import {Foo} from "foo.d";
When importing files with a *.d.ts extension, remember to follow this format for imports without having to make any configuration changes.

Answer №2

Encountering an unexpected challenge with NextJS 14 today prompted me to take action.

After some investigation, I found that I needed to explicitly define the typeRoots in my configuration file like so (previously undefined and utilizing an unknown default):

"typeRoots": [
  "@typings",
  "node_modules",
  "node_modules/@types"
],

To put it simply:

  • The @typings directory houses external type declarations (exclusively d.ts files).
  • node_modules may contain d.ts types as certain packages distribute them alongside their source code (this oversight caused issues during the execution of next build)
  • node_modules/@types serves as the repository for modules releasing their typings (a recommended practice not always adhered to).

Here's a snippet from my complete tsconfig.json setup:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Next.js",
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "baseUrl": ".",
    "types": [
      "node",
      "jest",
      "@testing-library/jest-dom"
    ],
    "typeRoots": [
      "@typings",
      "node_modules",
      "node_modules/@types"
    ],
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "**/*.mjs",
    "jest.config.js",
    ".next/types/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Does the Error page in Next JS 13 fail to properly manage fetch API errors?

After referencing the documentation for Next.js with app router, I followed the instructions to create an error.tsx page within my app folder (app/[lang]/error.tsx). This file contains the code provided in the docs. Additionally, I included some API calls ...

Using generics in props in a React functional component: Best practices and tips!

Creating a functional component that supports generics in props is a challenge for me. Usually, in a class based component I can easily write code like this: import * as React from 'react'; import { render } from 'react-dom'; interfac ...

Passing form data from Next.js to the parent page

I recently developed a basic web page called "Lucky Number" pages/lucky.js import finder from '../../hooks/use-finder' import NumberForm from '../components/number-form' export default function LuckyNumber() { const { data } = finder ...

The Observable merge operation encountered an error: it cannot access the 'apply' property of an undefined value

I am currently working on setting up a sorted DataTable in an angular application, and while implementing it using this example, I encountered the following error: ERROR TypeError: Cannot read property 'apply' of undefined at TableDataSource ...

Populating fields in one observable with data from a different observable in Typescript

Can someone help me with two requests? /users and /user/<id>/milpac /users returns a list of User[], while /user/<id>/milpac returns a milpac object. export class User { join_date: string; promotion_date: string; user_id: number; us ...

The async/await feature in Typescript fails to trigger updates in the AngularJS view

Currently, I am utilizing Typescript 2.1 (developer version) to transpile async/await to ES5. An issue I have encountered is that when I modify any property linked to the view within my async function, the view does not automatically reflect the updated v ...

Make sure to pause and wait for a click before diverting your

Having an issue with a search dropdown that displays suggestions when the search input is focused. The problem arises when the dropdown closes as soon as the input loses focus, which is the desired functionality. However, clicking on any suggestion causes ...

The 'items' property cannot be linked to 'virtual-scroller' as it is not a recognized attribute

I'm currently facing an issue with integrating virtual scroll into my Ionic 4 + Angular project. Previously, I relied on Ionic's implementation of virtual scroll (ion-virtual-scroll) which worked well initially. However, I encountered a major dr ...

Is there a way to mock a "find" call in mockingoose without getting back "undefined"?

I am currently working with mockingoose 2.13.2 and mongoose 5.12.2, leveraging Typescript and jest for testing purposes. Within my test scenario, I am attempting to mock a call to my schema's find method. Here is what I have tried: import mockingoose ...

Utilizing a setup module for configuration purposes

In the process of developing my angular application, I have integrated several external modules to enhance its functionality. One crucial aspect of my final application is the configuration classes that store important values like URLs and message keys us ...

What is the best way to account for the 'elvis operator' within a given expression?

When connecting to my data from Firebase, I noticed that using the elvis operator is essential to avoid encountering undefined errors. Recently, as I delved into creating reactive forms, I encountered an issue with a component I developed that fetches actu ...

Tips on revealing TypeScript modules in a NodeJS environment

Currently, I am working on developing a TypeScript library. My goal is to make this library compatible with both TypeScript and JavaScript Node projects. What would be the most effective approach for achieving this? Should I create two separate versions ...

I encountered an issue while trying to validate the private pusher channel for node/next.js

I have been developing a messaging notification system for my application. I created a ChatContext provider file that encapsulates the app and connects to Pusher when a user is logged in on page load. Each user will have their own private channel (private ...

Error Encountered during Compilation in Typescript-Angular5

I have been working on implementing a login feature with angular5, but I have encountered several issues along the way. While I managed to resolve some of them, I am currently facing a compilation problem: ERROR in src/app/login/login.component.ts(38,3): ...

Encountering an issue with importing mongoose models while trying to create a library

I've been working on creating a library of MongoDB models and helper classes to be shared as an npm module with the rest of my team. However, I'm facing an issue with the main code that I import from lib MongoConnector which processes configurati ...

Encountering an issue with React Redux and Typescript involving the AnyAction error while working on implementing

While integrating redux-persist into my React project, I encountered an error. Previously, Redux was working smoothly, but upon the addition of redux-persist, I started receiving this error message: Types of property 'dispatch' are incompatib ...

Achieving a similar functionality to Spring Security ACL in a Node.js AWS Lambda serverless environment

I am tackling a javascript challenge that has me stumped. Specifically, I am trying to figure out how to implement fine-grained authorization using an AWS serverless approach. In Spring security ACL, users can be banned from specific tasks at the instanc ...

Achieving seamless integration among react-templates, TypeScript, and webpack

I am attempting to integrate TypeScript, react-templates, and webpack for a seamless workflow. My starting point was the sample code provided at https://www.typescriptlang.org/docs/handbook/react-&-webpack.html. The configuration in the webpack.config ...

Unit Testing in Angular: Leveraging Generics for Component Creation

I'm attempting to develop a universal wrapper for TestBed.createComponent, where it takes a type argument and generates the component based on that type. Unfortunately, the TestBed.createComponent function necessitates an argument of type Type<T> ...

Struggling with using Redux with tassign in Angular (typescript) to combine state.array and action.array. However, encountering an issue where state.array.join is not a function

Redux function to combine all videos: function combineAllVideos(state, action) { return tassign(state, { allVideos: state.allVideos.concat([action.data]) }); } Declaration + State for all videos array: allVideos: Array<Object>; OR allVid ...