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

Displaying Firebase data using Angularfire2 5.0 on an Ionic template

Hey everyone, I've been encountering a problem while trying to use angularfire2 v 5.0. I was comfortable using v 4.0 before, but now that I'm transitioning to v 5.0, I'm facing some issues. Does anyone know how I can display real-time data ...

Using babel with node.js version 18 allows you to easily import modules with various extensions and run them from the build folder configured with commonJS. Ensure that you have specified "type:module"

I'm currently utilizing Node.JS version 18.20.4 alongside Babel. Below is my babel.config.json: { "presets": [ [ "@babel/preset-env", { "targets": { "node": 18 }, ...

What is the significance of the character "^" in versioning within a package.json file?

After running npm install (version 1.4.3) with the --save-dev option, I noticed that all the package entries it added to my package.json started with a ^, such as "^2.5.0". This is new to me as I have never encountered this notation in previous versions ...

What could be causing the error "Type 'String' cannot be used as an index type" to appear in my TypeScript code?

My JavaScript code contains several associative arrays for fast object access, but I'm struggling to port it to TypeScript. It's clear that my understanding of TypeScript needs improvement. I've searched for solutions and come across sugges ...

Incorporating @mdi/font into Laravel (version 7.2): A step-by-step guide

Trying to integrate the package from into my brand new Laravel (version 7.2) project. So far, I have executed the following command: npm install @mdi/font I can confirm that the package has been successfully installed by checking it in the image below: ...

Encountered an issue while trying to read the property 'temp' of undefined within an HTML document

Can someone help me with this issue? I'm facing an error with the JSON data retrieved from an API: ERROR in src/app/weather/weather.component.ts(39,30): error TS2339: Property 'main' does not exist on type 'Iweather[]' Here is ...

Encountered an issue when attempting to utilize `npm start` within a React JS project following

https://i.stack.imgur.com/yII3C.png Whenever I attempt to run npm start in the vsCode terminal, an error pops up as shown in the image above. In the picture provided, you can see that my package.json only contains a start script. Can anyone offer assistan ...

What is the best method to remove a value from a JSON object in a CSV file?

I received a JSON response like this: xxx: ["fsd,das"] I am looking for a way to remove the value "fsd" from the JSON object. The issue is that the response inside the JSON is not actually an array, but rather a CSV format. How can I go about deleting it ...

Send a variable to the npm command's string parameter (and not to the script executed by the npm command)

Is it feasible to include an argument in the npm command string? I have searched through the documentation but couldn't find any relevant information. It would be advantageous for a wide audience to know how to do this. For instance, consider the fol ...

What is the reason for using 'Input' as a type instead of referring to it as a value? TS 2749

The file format is correct as .tsx, however, there seems to be an issue with using HTMLInputElement instead of Input. In my opinion, it should be Input since it relates to the assigned value. Can you help identify the problem in the code snippet below at l ...

Exploring the nuances of checking lists in TypeScript

In the following list: empList = ['one','two','finish','one','three'] I am required to evaluate conditions based on empList: Condition 1: If 'two' appears before 'finish', set this ...

Tips for setting up Azure Maps and installing version 3 of the azure-maps-control package

Upon attempting to install the latest version 3.x of the npm package azure-maps-control, I encountered some issues with Typescript: The package references an azuremaps-maplibre-gl module that appears to be missing. While a regular maplibre-gl module exist ...

Having trouble with your npm installation getting stuck on Windows 10 during the fetchMetadata process?

https://i.stack.imgur.com/n6IdJ.png After the message was displayed, no further actions occurred... I'm really puzzled as to why. https://i.stack.imgur.com/5u0AT.png ...

The command 'node' is not identified as an internal or external command, executable program, or batch file

While running "npm install node-sass" from git-bash-cli in Windows 10, I encountered a "'node' is not recognized as an internal or external command, operable program or batch file." error. This setup worked fine for years until I upgraded Node t ...

Variety of properties determined by a "type" prop, expanding variations based on a value from the interface

I am trying to enhance a type based on a value from the main interface. If the type == multiline, it will have a specific interface, and if the type == icon, it will have a different type. import React, { memo, useCallback, ReactNode } from 'react&apo ...

Issue with Angular 8: click event is not triggering when using ngFor directive to iterate through arrays of objects

Update: The original post has been modified to omit implementation details and complexity. I am facing an issue with an ngFor loop that invokes a method on a service. The method returns an array which is then iterated over by the for loop. The click even ...

Browser with Node's https.Agent

In my npm package written in TypeScript, I utilize axios to make web requests. One of the endpoints requires certificate authentication, so I pass new https.Agent to axios to include the necessary certificates. Everything works perfectly when the module is ...

"Encountered an error: Expo command not recognized on Mac operating system

As I dive into the world of react native and embark on my initial project, I encounter an issue while installing the expo cli. After what appears to be a successful installation, I receive this message: + <a href="/cdn-cgi/l/email-protection" class="__c ...

Prevent receiving the "deprecated warning for current URL string parser" by enabling the useNewUrlParser option

I recently encountered an issue with my database wrapper class that connects to a MongoDB instance: async connect(connectionString: string): Promise<void> { this.client = await MongoClient.connect(connectionString) this.db = this.cli ...

Can you explain the distinction between "parser" and "parserOptions.parser" in an ESLint configuration?

For a considerable amount of time, I have been using the TypeScript and Vue presets provided below. While it has been functional, I realize that I do not fully comprehend each option and therefore seek to gain a better understanding. Firstly, what sets apa ...