Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

declare module in typescript with both default and named exports

I am using a library called "react-images" which doesn't have up-to-date type definitions. As a result, I need to open up the namespace and create them. The problem is, the library has both default and named exports and I'm having trouble getting typescript to handle both kinds of exports correctly.

Named imports work out of the box, all you need to do is declare the classes. If you want a default export though, you need to use the export syntax discussed here. Unfortunately, when I added the line export = Carousel, the named imports broke.

I need to be able to do this:

// project.tsx

import Carousel, { Modal, ModalGateway } from "react-images";

Here's what I've got so far:

// reactImages.d.ts

import React from "react";

declare module "react-images" {
  interface ModalProps {
    onClose: () => void;
  }

  declare class Modal extends React.Component<ModalProps> {
    public constructor(props: ModalProps);
  }

  declare class ModalGateway extends React.Component<> {
    public constructor(props: ModalGatewayProps);
  }

  interface CarouselProps {
    currentIndex: number;
    views: { source: string }[];
  }

  declare class Carousel extends React.Component<CarouselProps> {
    public constructor(props: CarouselProps);
  }
  export = Carousel
}
like image 529
williamcodes Avatar asked Nov 15 '22 20:11

williamcodes


2 Answers

Try this:

export { Modal, ModalGateway };
export default Carousel;
like image 93
Jon Sakas Avatar answered Dec 09 '22 23:12

Jon Sakas


Since I haven't found any solution anywhere, I would like to share my solution. The key is to create an interface with default anonymous method and export a variable instance of this interface.

Example

module.d.ts

interface GeoTz {
    /**
     * Get TZ ids for lat/lon. It can throw an exception if coordinates are invalid.
     *
     * @param lat Latitude
     * @param lon Longitude
     * @returns TZ ids for coordinates, e.g. ['Asia/Shanghai', 'Asia/Urumqi']
     * @throws An exception if coordinates are invalid
     */
    (lat: string | number, lon: string | number): string[];

    /**
     * Can change the cache behavior, such as preload everything into memory or use custom get/set store functions
     *
     * @param opts Custom options for cache
     */
    setCache(opts: {
        preload?: boolean;
        store?: {
            get: (key: string) => import('geojson').GeoJSON;
            set: (key: string, data: import('geojson').GeoJSON) => void;
        };
    }): void;
}

declare module 'geo-tz' {
    const geoTz: GeoTz;
    export = geoTz;
}

Then in code both works:

import geoTz from 'geo-tz';

geoTz.setCache({ preload: true });
geoTz('49.000', '14.000');

like image 22
Marek Dorda Avatar answered Dec 09 '22 22:12

Marek Dorda