0

I was going through one of the repo to see how people structure their ts repo.

I went through their typings and saw this

/**
 * 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 am unable to figure out when should we use declare module or declare namespace? The closest I was able to come across with this answer on stackoverflow but I think this shares the difference between the both and not when to use them (and which one to use)

The typescript handbook states this

This post outlines the various ways to organize your code using modules and namespaces in TypeScrip

And I wasn't able to comprehend the definition of the above.

Alwaysblue
  • 9,948
  • 38
  • 121
  • 210

1 Answers1

0

In my experience, declare module and declare namespace are most useful in the context of Declaration Merging. Basically, since in Javascript you can monkeypatch the prototypes of classes or add properties to third party classes, declaration merging gives you a way of exposing those dynamic changes to the behaviour of an object in the type system.

For example, consider the Request object from express.js. The API exposed by express does not expose something like a field for a request id. However, it is customary in javascript to simply mutate the request object.

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

Typescript doesn't like this however because with the normal express type definitions, id is not a property of request. You can fix by using declare module and declaration like this:

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;
  }
}

If you include this file in your type path, Typescript will be happy to accept the optional id property of Request. The use case for declare namespace is similar.

John Dengis
  • 192
  • 1
  • 8