Guide to setting up an interface-only project (along with its dependent projects) on NPM

I'm encountering two problems with my TypeScript project.

Imagine I have a interface-only TypeScript project called myproject-api. My plan is to implement the interfaces in two separate projects named myproject-impl1 and myroject-impl2. I am utilizing Lerna to manage these modules as part of a root project named myproject, all of which have been appropriately bootstrapped using npm link. Additionally, I am using gulp for transpilation of TypeScript source code, with a simple configuration setup at this point.

Problem 1: Despite adding "types": "dist/main.d.ts" or "types": "src/index.ts" to the package.json file, the implementation module is unable to recognize the type definitions from myproject-api. Even moving myproject-api/src/index.ts to myproject-api/index.ts did not solve the issue. The compiler consistently throws an error stating

Cannot find module 'myproject-api'.

Problem 2: It appears that TypeScript does not generate the .d.ts files if there are no actual implementations in the .ts source files, unless I compile the project specifically using tsc -d --outFile dist/main.js. Essentially, when compiling with the tsconfig.json configuration (e.g., tsc --project tsconfig.json), the .js files are generated but not the .d.ts files.

P.S.: This project was initiated to refine some conceptual ideas I had in mind. If anyone has suggestions for improving this project layout, I would appreciate your input.


More Information...

All .ts projects utilize ES6 imports.

Here is the folder structure:

.
├── lerna.json
├── package.json
├── packages
│   ├── myproject-api
│   |   ├── dist
│   │   ├── gulpfile.js
│   │   ├── package.json
│   │   ├── src
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── myproject-impl*
│       ├── dist
│       ├── gulpfile.js
│       ├── package.json
│       ├── src
│       │   └── index.ts
│       └── tsconfig.json
└── README.md

packages/myproject-api/src/someClass.ts
:

export interface ISomeClass { /* ... */ }

packages/myproject-api/src/index.ts
:

export * from "./someClass.ts"
// (repeating this kind of export for all inner modules)

packages/myproject-impl*/src/index.ts
:

import { ISomeClass } from "myproject-api"
// ...

Gulp Configuration:

var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

gulp.task("default", ["build"]);

gulp.task("build", function () {
    return tsProject.src()
        .pipe(tsProject())
        .js.pipe(gulp.dest("."));
});

This represents the shared tsconfig.json across all projects:

{
    "compilerOptions": {
        "target": "es6",
        "module": "amd",
        "strict": true,
        "baseUrl": ".",
        "outFile": "dist/main.js",
        "declaration": true,
        "lib": [
            "es5",
            "es2015.promise",
            "es2015.iterable"
        ]
    },
    "exclude": [
        "node_modules",
        "dist"
    ]
}

System Information:

[flisboac@sonic ~]$ tsc --version
Version 2.6.2
[flisboac@sonic ~]$ node --version
v9.3.0
[flisboac@sonic ~]$ lerna --version
2.5.1
[flisboac@sonic ~]$ gulp --version
[03:39:24] CLI version 2.0.0
[flisboac@sonic ~]$ npm --version
5.6.0
[flisboac@sonic ~]$ uname -a
Linux sonic 4.14.6-1-ARCH #1 SMP PREEMPT Thu Dec 14 21:26:16 UTC 2017 x86_64 GNU/Linux
[flisboac@sonic ~]$ lsb_release -a
LSB Version:    1.4
Distributor ID: Arch
Description:    Arch Linux
Release:    rolling
Codename:   n/a

Answer №1

Thanks to the advice from @OJKwon, utilizing --traceResolution was key in helping me solve the issue at hand. As outlined in the module resolution documentation, it became clear that tsc only pays attention to package.json if you explicitly set "moduleResolution": "node" within the confines of tsconfig.json, as opposed to the default setting which is "moduleResolution": "classic". The reliance on index.ts as a standard import format applies exclusively to the node resolution method.

In addition, I found that restarting VSCode was necessary in order for the imports to be resolved accurately.

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

Sequelize fails to update when attempting to modify only the renamed updatedAt attribute

Ever since I upgraded to Sequelize v5 (from 4.x.x), the following code no longer works: await myModel.update({ date_updated: new Date() }, { where: { id: obj.id } }); In my model, I have aliased that field as updatedAt: ... updatedAt ...

Retrieve files from Amazon S3 using JavaScript

I'm currently working with a javascript file that's intended to download a text file from one of my S3 buckets. However, after running this file using "node file.js", nothing happens and there's no output. Is there something I'm missing ...

How to easily transfer a JSON file to a server using Vue and Node.js

As a newcomer to the world of Node.js and Vue development, my goal is to establish a seamless process for users to create and upload a JSON file to the server when they save data in a form. This process should occur effortlessly in the background, allowing ...

What should be the proper service parameter type in the constructor and where should it be sourced from?

Currently, I am faced with a situation where I have two Angular 1 services in separate files and need to use the first service within the second one. How can I properly type the first service in the constructor to satisfy TypeScript requirements and ensure ...

Leveraging the Image data type in SQL Server to showcase images in an Angular 2.0 environment, with the response handled by Express

I am receiving the following response from Express and I am looking to display the supertendentsSignature image in Angular 2. Database: SQL Server Dataytpe : Image ORM: Sequelize Datatype of SuperintendentsSignature column is Blob Framework : Express Fro ...

What sets npm install apart from npm update?

Can you explain the real distinction between npm install and npm update? In what situations should I opt for each one? ...

Achieving a delayed refetch in React-Query following a POST请求

Two requests, POST and GET, need to work together. The POST request creates data, and once that data is created, the GET request fetches it to display somewhere. The component imports these hooks: const { mutate: postTrigger } = usePostTrigger(); cons ...

An EJS array nested within an object

Below is the nodejs(express) code snippet: response.redirect('file', {test: [{name:'sarah', arr:[1,2,3]}, {name:'beck', arr:[2,3,4]}]} In my ejs file, I am trying to access the 'arr' for each name in the arra ...

Tips for resolving Typescript type error when overriding MuiContainer classes

My application is divided into two main files: (https://codesandbox.io/s/react-ts-muicontainer-override-yywh2) //index.tsx import * as React from "react"; import { render } from "react-dom"; import { MuiThemeProvider } from "@material-ui/core/styles"; imp ...

Resolve the upstream dependency conflict that occurs during the installation of ng-bootstrap/ng-bootstrap

Encountering an error while attempting to install npm install --save @ng-bootstrap/ng-bootstrap. Seeking assistance in resolving this issue. npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: <a ...

Converting ts files to js: A comprehensive guide

I am looking for a way to transform my TypeScript files into JavaScript files smoothly. The conversion process goes well with the command: nodemon --watch assets/ts --exec tsc assets/ts/*.ts --outDir assets/js However, I have encountered an issue where im ...

Ways to convert an object with values into an array containing those values

To process the JSON data and convert it into an array with the same values for insertion into my PostgreSQL database using pool.query(message, values), where values should be an array if multiple are present. Currently, my object structure is as follows: { ...

What is the best way to forward a file upload request from a Next.js API to another API?

Trying to crop an image within a Next.js application, then sending it through an API route within the app before reaching an external API endpoint is proving to be a challenge. The process works fine without going through the API route, but once that step ...

Tips for resolving the npm ResourceUnavailable issue

Hey there! I'm currently experimenting with React. In my folder, I've got nodejs along with npm and npx files installed. While debugging, I've deleted and reinstalled this folder multiple times. However, no matter what directory or command I ...

Can I send a request to an Angular server from a Node.js server?

I am currently running two servers, one with NodeJS and the other with Angular. My NodeJS server is listening on port 3000, while my Angular server is listening on port 8000. I am wondering if it is possible to access my Angular website through localhost:3 ...

Nested Promise.all within another Promise.all appears to terminate prematurely, triggering a warning indicating failure to return from a promise

I am utilizing this function to be invoked within another Promise.all. However, I consistently encounter a warning message: Caution: a promise was generated in a handler but was not returned from it. Additionally, the function deleteFutureAppointments() ap ...

`Should I utilize the node-postgres package pool or client and when?`

After extensive research on this topic, I am currently utilizing the pool. However, I am uncertain about the variance between the two options. Can someone clarify? const { Client } = require('pg') const client = new Client() await client.conn ...

Create a Mongoose model that includes a field containing an array of ObjectID's

I am encountering an issue with my object named company, which contains keys for name(String) and locations(Array). Within the locations key, I want to include a user-generated key called name, as well as a second key generated using ObjectID. However, I a ...

Demonstrate JSON data using ngFor loop in Angular

Need some assistance here. Trying to display data from a .json file using a ngFor loop. However, I keep running into the following error in my code: Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgF ...

The module specifier "tslib" could not be resolved due to a TypeError. It is necessary for relative references to begin with either "/", "./", or "../"

Hey there, I recently started learning npm. I'm trying to install "@fullcalendar" and use it, but I keep getting this error message: "Uncaught TypeError: Failed to resolve module specifier "tslib". Relative references must start with either "/", "./", ...