What factors should I consider when determining whether to include @types/* in the `dependencies` or `devDependencies` section?

Currently using TypeScript 2 in my project, I am looking to incorporate a JavaScript library along with its typings. While I know I can easily install the types using npm install @types/some-library, I am uncertain whether to use --save or --save-dev. The DefinitelyTyped GitHub readme vaguely mentions both options without clarification. My instinct tells me that @types should be included in devDependencies, since the types are strictly for development purposes and not utilized during runtime. However, I have noticed @types being placed in dependencies numerous times, adding to my confusion.

How can I determine whether @types/* belongs in dependencies or devDependencies? Are there any formal guidelines available on this matter?

Answer №1

Imagine you're working on a project called "A" which relies on the @types/some-module package in the devDependencies. You decide to export the type from @types/some-module:

import { SomeType } from 'some-module';

export default class APackageClass {
  constructor(private config: SomeType) {
    // …       
  }
}

However, TypeScript consumers of project "A" won't be able to understand what SomeType is without having the devDependencies installed.

In this specific scenario, it's crucial to move the @types/* package to regular dependencies. For other situations, keeping them in devDependencies should suffice.

Answer №2

If you're in the process of generating a bundle, it may not be necessary to differentiate between dependencies and devDependencies. This functionality within npm is typically more useful when releasing a package for others to use, as it helps avoid overwhelming them with unnecessary dependencies.

While there are scenarios where separating dependencies can be beneficial, unless you have a specific requirement for it, my suggestion would be to simply choose one category and place all dependencies there. If needed, it's easy enough to split them later on.

An example commonly seen in practice is with create-react-app, where the initial boilerplate setup places all dependencies under dependencies by default. You can refer to this discussion thread and this response for more insight.

Answer №3

When deploying a Node.js application to production, it is important to only install the necessary dependencies for running the application.

npm install --omit=dev or

npm ci --production or

yarn --production

In order to prevent unnecessary bloat during installation, types should be included in the devDependencies.

(It's worth noting that using the --production or --omit=dev option on machines where the application is built may cause issues with the TypeScript compiler.)

Note: This insight was originally mentioned by Brad Wilson in a comment on another answer, but it deserves its own separate response.

Answer №4

Considering the intended use of your code is crucial. If you plan to incorporate the types into your final product (e.g. when building a custom package that includes these types), they should be included in the dependencies section. However, if the types are only needed during development, it would be more appropriate to include them in the devDependencies section.

Answer №5

In addition to the insightful responses provided, it is worth mentioning that a peerDep's type declaration package should be included in the dependencies section rather than the peerDependencies section.

Consider the scenario where b serves as a plugin for a, and c utilizes both a and b.

Why is it not advisable to place @types/a within the peerDependencies of b?

If the package.json file of b looks like this:

{
  "peerDependencies": {
    "a": "1.5.x"
    "@types/a": "1.4.x"
  }
}

c will only use interfaces defined in

@types/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c5a485f4ebf7ebbd">[email protected]</a>
, but it will be required to install
@types/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8b998e9f6ecf6a0">[email protected]</a>
.

Moreover, even if c is just a regular JavaScript package and not a TypeScript package, it will still need to install

@types/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="177657263923396f">[email protected]</a>
unnecessarily.

Hence, the correct structure for the package.json of b should be:

{
  "peerDependencies": {
    "a": "1.5.x"
  },
  "dependencies": {
    "@types/a": "1.4.x"
  }
}

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

What is preventing type guarding in this particular instance for TypeScript?

Here is an example of some code I'm working on: type DataType = { name: string, age: number, } | { xy: [number, number] } function processInput(input: DataType) { if (input.name && input.age) { // Do something } e ...

Dynamic user input using an enumeration

I am looking to develop a flexible input component (in React) that can dynamically generate different types of inputs based on the enum type provided along with relevant inputProps. The idea is to switch between different input components based on the type ...

Encountering an error when attempting to include React TypeScript onChange with a Material UI switch component

I'm working on implementing a show/hide functionality using a switch. I want the component to be displayed when the switch is turned on and hidden when it's turned off. Here's the code I've written: const VirtualEventSection = ({ con ...

Can getters and setters be excluded from code coverage reports in Angular projects?

Looking to clean up my coverage reports for the front end portion of an angular project by removing trivial code like getters and setters. I generate my reports using npm run test-sonar -- --coverage, but everything is included in the report when I view ...

How can I access members outside of a class without a name in Typescript?

I recently developed an "anonymous" class inspired by this insightful discussion on Typescript anonymous classes. However, I'm facing a challenge in accessing the outer scope members. Here's a snippet of my code for context: class BaseCounter { ...

The command 'typings' is not recognizable as an internal or external command, executable program, or batch file

update: ever since this question was posted, the use of typings has been phased out in favor of @types. Overview I'm attempting to set up typescript typings for my web application, but I'm encountering an issue where the command prompt does n ...

Is it possible to include additional options in the dependencies section of npm package.json file?

I am facing an issue with the sqlite3 package dependency. Normally, when installing the sqlite3 package, it automatically downloads and uses a pre-packaged version of the sqlite3 engine. However, this can cause problems when working with sqlite3 extension ...

How to update a private NPM module from a Git repository and maintain its installation?

After reviewing this helpful answer on installing npm modules from private git folders, I successfully followed the steps outlined. By using npm install git+ssh://<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c3a4aab783a4aab7a ...

Generating a custom node package archive for a lambda function using an npm workspace folder

My monorepo setup includes npm workspaces, and once it's installed it appears like this: / package.json node_modules/ packages/ lambda/ node_modules/ package.json package-lock.json <source code> cdk-stacks/ ...

When Typescript and React Native Imports Clash in an Express App, Resolving the Conflict of "npm run build" Command

When running my Express app using 'npm run serve', defined as 'npm run build && node lib/index.js' in the package.json scripts serve section, I encounter multiple duplicate declaration errors after installing React Native for a ...

I am having difficulty accessing the values stored in my cardTiles variable

I am facing an issue with a variable called cardTiles in my Angular 9 component. The variable is defined as cardTitles:Product[] = []; The Product class is defined as follows export class Product{ productName: string;} When I console.log(this.cardTi ...

I am experiencing difficulties deploying my React app through the npm run deploy command

I'm seeking guidance on troubleshooting the deployment of a React site from Github to Netlify. My deployment code is: npm run deploy Here is the error message displayed in the terminal: npm ERR! code ELIFECYCLE npm ERR! file sh npm ERR! errno ENOENT ...

Retrieve an instance of the property class within a property decorator

I'm attempting to create a decorator called @Prop that will assist me in adjusting attributes for custom elements. This is the desired code: class MyCustomClass extends HtmlElement { get content() { return this.getAttribute('content&apo ...

Semantic-release failing to generate a new version update for package

I'm in the process of setting up semantic release for my NPM package to automate deployment with version updates. However, after migrating from an old repo/npm package to a new one, I'm facing issues with semantic versioning not creating a new re ...

Issue: Button ClickEvent is not triggered when the textArea is in onFocus mode

Is there a way to automatically activate a button ClickEvent when the textArea input is focused? Keep in mind that my textArea has some styles applied, causing it to expand when clicked. Here is an example: https://stackblitz.com/edit/angular-ivy-zy9sqj?f ...

Is there a way to identify the global node dependencies being utilized by my application?

My initial attempt to deploy my app on AWS Elastic Beanstalk has encountered a hurdle. It seems that certain dependencies, which were installed locally on my development machine, are missing from the node_modules folder of the app that I uploaded to AWS. ...

Using [(ngModel)] in Angular does not capture changes made to input values by JavaScript

I have developed a custom input called formControl, which requires me to fetch and set its value using [(ngModel)]: import { Component, Injector, OnInit, forwardRef } from '@angular/core'; import { ControlValueAccessor, FormControl, NG_VALUE_ACCE ...

Strategies for packaging and integrating dependencies within Angular-CLI libraries

I am encountering difficulties with bundling dependencies in my project. The library package I have created serves as a wrapper for @angular/material components. To my surprise, each time I install my library package, the installation process also prompt ...

How do React Native proxies differ from vanilla React proxies in their functionality?

Trying to retrieve data from an API running locally on port 5000 of my device, I recalled setting the proxy in package.json when working on React web applications: "proxy": "https://localhost:5000" Attempting to fetch information f ...

The 'fullDocument' property is not present in the 'ChangeStreamDropDocument' type

Upon cloning an express TypeScript project, I encountered a Typescript error within a Mongo related function as mentioned in the title. Property 'fullDocument' does not exist on type 'ChangeStreamDocument<IUser>'. Property &apos ...