Determining the appropriate scenarios for using declare module and declare namespace

Recently, I came across a repository where I was exploring the structure of TypeScript projects. One interesting thing I found was their typings file:

/**
 * react-native-extensions.d.ts
 *
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT license.
 *
 * Type definition file that extends the public React Native type definition file.
 */

    import * as React from 'react';
    import * as RN from 'react-native';
    import * as RNW from 'react-native-windows';
    
    declare module 'react-native' {
        interface ExtendedViewProps extends RN.ViewProps

 {

Now, I'm puzzled about when to use declare module or declare namespace. Although I found a stackoverflow answer explaining the difference between them, it didn't provide guidance on when and which one to use.

In the TypeScript handbook, there is an explanation of different ways to organize code using modules and namespaces in TypeScript, but it was quite confusing for me to understand.

Answer №1

In my personal experience, the utilization of declare module and declare namespace has proven to be most valuable within the realm of Declaration Merging. Essentially, since it is possible in JavaScript to patch the prototypes of classes or append properties to third-party classes, declaration merging provides a method of exposing these dynamic modifications to the behavior of an object in the type system.

For instance, let's consider the Request object from express.js. The API offered by Express does not inherently provide a field for a request ID. However, within the context of JavaScript, it is customary to simply modify the request object accordingly.

middlware(req, res, next) {
  req.id = uuid.v4()
  next()
}

Nevertheless, TypeScript does not approve of this practice because, according to the standard express type definitions, id is not recognized as a property of request. This issue can be resolved using the combination of declare module and a declaration similar to the following:

import { Request } from "express";
import core from "express-serve-static-core";

declare module "express" {
  interface Request<
    P extends core.Params = core.ParamsDictionary,
    ResBody = any,
    ReqBody = any,
    ReqQuery = core.Query
  > {
    /**
     * An optional request id that can be attached to the request. Useful for correlating
     * and searching log messages.
     */
    id?: string;
  }
}

By including this file within your type path, TypeScript will readily accept the optional id property of Request. The use case for declare namespace is quite similar.

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

Jest tests are failing to render React IonDateTime component

While executing Jest on an Ionic React component, I encountered a test failure consistently, regardless of whether the component had a time value or not. test('IonDateTime display', () => { render(<IonDatetime data-testid="foo" ...

Enhancing collaboration: Seamlessly sharing interface/interface/model files in the integration of

Currently, I am engrossed in developing an application with an Express backend and Typescript whilst utilizing Angular for the frontend. The only snag I'm facing is that I require interface/models files from the backend to be accessible on the fronten ...

Guide on creating a Typescript function with a strongly typed argument

I am looking to develop a function that accepts a type created using export class and imported in the traditional manner as an extension of a particular type. With a base Page class and various derived classes, I aim to have this function capable of receiv ...

Can you explain the functionality of `property IN array` in the TypeORM query builder?

I'm looking to filter a list of entity ids using query builder in an efficient way. Here's the code snippet I have: await this._productRepo .createQueryBuilder('Product') .where('Product.id IN (:...ids)', { ids: [1, 2, 3, 4] ...

Detect errors in the `valueChanges` subscription of Firestore and attempt a retry if an error occurs

My Angular app utilizes Firestore for storing data. I have a service set up to retrieve data in the following way: fetchCollectionColors(name) { this.db.collectionGroup('collection-colors', ref => ref.where('product', '==&ap ...

Tips for creating a sequelize transaction in TypeScript

I am currently working with sequelize, node js, and TypeScript. I am looking to convert the following command into TypeScript. return sequelize.transaction().then(function (t) { return User.create({ firstName: 'Homer', lastName: ' ...

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 ...

Bring in typings from a package with an alternate title

I have a project that I am currently converting to typescript. In this project, I am using the package ng-idle. Additionally, there is a corresponding @types package named angular-idle, which contains the file @types/angular-idle/index.d.ts with the follow ...

Is there a way to determine if a string is empty, even if it contains hard returns?

I am currently working on a function that checks if a string is empty or not, but it seems to be missing the detection of new lines. export const isStrEmpty = function(text: string): boolean { return !text || text.match(/^ *$/) !== null; }; I attempted ...

Modifying a property in a nested layout through a page in Next.js 13

Currently, I am facing a challenge in updating the page title within a nested layout structure. app/docs/layout.tsx: export const DocsLayout = ({children}:{children: React.ReactNode}) => { return ( <> <header> ...

Ways to encourage children to adopt a specific trait

Let's discuss a scenario where I have a React functional component like this: const Test = (props: { children: React.ReactElement<{ slot: "content" }> }) => { return <></> } When a child is passed without a sl ...

Is it possible to compile using Angular sources while in Ivy's partial compilation mode?

Error: NG3001 Unsupported private class ObjectsComponent. The class is visible to consumers via MasterLibraryLibModule -> ObjectsComponent, but is not exported from the top-level library entrypoint. 11 export class ObjectsComponent implements OnInit { ...

Compiling TypeScript to JavaScript with Deno

Currently experimenting with Deno projects and looking for a way to transpile TypeScript into JavaScript to execute in the browser (given that TS is not supported directly). In my previous experience with NodeJS, I relied on installing the tsc compiler via ...

Angular 5 Image Upload - Transfer your images with ease

I am having trouble saving a simple post in firebase, especially with the image included. This is my current service implementation: uploadAndSave(item: any) { let post = { $key: item.key, title: item.title, description: item.description, url: '&a ...

Using Angular Material to dynamically hide columns in a table that is being created on the fly

Is there a way to hide columns in my table based on the ID value sent to the page upon opening it? While researching, I found a method for tables with dynamically generated columns in this post: https://github.com/angular/components/issues/9940. However, t ...

Initializing various objects on the same interface type array in one line

Is there a way to inline initialize an array of the interface type IFooFace in TypeScript with different specific implementations, similar to how it can be done in C#? Or do I have to initialize my objects before the array and then pass them in? In C#, th ...

In Angular, when a component is clicked, it is selecting entire arrays instead of just a single item at a

I am currently working on implementing a rating feature using Angular. This component will be used to rate different languages based on how proficient I am with them. My issue lies in the fact that when I click on one array element, it automatically selec ...

When working with TypeScript, it's important to note that an implicit 'any' type may occur when trying to use an expression of type 'string' to index a specific type

Currently, I'm attempting to transfer a custom hook used in Vue for handling i18n from JavaScript to TypeScript. However, I am encountering a persistent error message: An element is implicitly assigned the type 'any' due to an expression o ...

Accessing file uploads in Angular 2

<div class="fileUpload btn btn-primary"> <span>Select File</span> <input id="uploadBtn" type="file" class="upload" value="No File Chosen" #uploadBtn/> </div> <input id="uploadFile" placeholder="No File Selected" disable ...

What steps should I take to ensure that a cookie has been properly set before utilizing it?

I'm in the process of developing a JWT authorization code flow using Next.js and NestJS. Below is the POST request being sent from the frontend to the backend server: const response = await fetch( 'http://localhost:4000/auth/42/callback?code=& ...