Bringing in additional types with the primary import using import/require

I am currently creating a definition file for Airtable, and I have encountered an issue with the way they export their classes. They only provide one class like this:

...

module.exports = Airtable;

As a result, my airtable.d.ts file looks something like this:

declare module "airtable" {
    export type CustomType = { ... };

    export class Airtable {
        ...
    }

    export = Airtable;
}

When I try to import the Airtable class, everything works smoothly:

import Airtable = require("airtable");
...
new Airtable(...)

However, I am struggling to figure out how to import the CustomType:

let a: Airtable.CustomType;

This line results in the following error:

'Airtable' is only referring to a type and cannot be used as a namespace here.

And when I try this approach:

import { CustomType } from "airtable";

I get these errors:

The module "airtable" does not have an exported member called 'CustomType'.
The module "airtable" resolves to a non-module entity and cannot be imported using this method.

Do you have any suggestions on how I can import other exported types while still utilizing export = and import/require?
Thank you.

Answer №1

The answer depends on how you plan to utilize the types. If they are for your own project, create a file named `<whatever>.d.ts` that declares a module called "airtable". Within this file, you need to export something. Since you are exporting a class, use the syntax export = X instead of export X as you are modifying the entire export object rather than adding a property to it (more details on this shortly). Regarding types, outside the module in your .d.ts file, you can also declare a type that will be globally accessible. Alternatively, you can place your type inside a module if you prefer. This is purely TypeScript and does not require any JavaScript code behind it. You can import/export it as usual:

// my.d.ts

declare module 'airtable' {
  class Airtable {
    constructor(opts?: MyType)
  }
  export = Airtable
}

declare type MyType = string | number

declare module 'AirtableTypes' {
  export type MyString = string
  export type MyNumber = number
}

Usage example:

// index.ts
import Airtable from 'airtable'
import AirtableTypes from 'AirtableTypes'

const a = new Airtable('a')

const n: MyType = 3

const s: AirtableTypes.MyString = '3'

If you wish to contribute types to DefinitelyTyped (which would be appreciated!), follow the guide outlined here to create the declaration file.

You rightly observed that Airtable exports a single class, which may not integrate well with TS. Further discussion can be found here. Regardless, the provided guide will direct you to module-class.d.ts, enabling you to define an exported class along with accompanying types. In the example above, this format could not be used since it is only applicable when definition files are located in the module root or @types/<module>.

/*~ This declaration ensures that the class constructor function
 *~ is the exported object from the file
 */
export = Airtable

/*~ Define your module's methods and properties within this class */
declare class Airtable {
  constructor(opts?: Airtable.AirtableMethodOptions)
}

/*~ If you want to expose types from your module, include them here.
 */
declare namespace Airtable {
  export interface AirtableMethodOptions {
    endpointUrl: string
  }
}

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

Can you provide guidance on implementing Material-UI's `withStyles` decorator in a practical scenario?

I'm currently solving the challenge of annotating the types for the different styles in my code. After converting from plain JavaScript to TypeScript, I am now adding type annotations. Here is a snippet of the code: import * as React from 'react ...

React type error: The argument 'profile' cannot be assigned to the parameter of type 'ComponentType<never>'

I've recently started learning TypeScript and I'm struggling with this particular issue. Below is the code I'm working on. import { IProps, IState } from './types'; class Profile extends Component<RouteComponentProps & I ...

Leveraging an AngularJS service within Angular framework

I am trying to incorporate an AngularJS service into my Angular project. Below is my main.ts file: import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {AppModule} from './app/app.module'; import {UpgradeMo ...

Encountering incorrect month while utilizing the new Date() object

My Objective: I am looking to instantiate a new Date object. Snippet of My Code: checkDates (currentRecSec: RecommendedSection){ var currActiveFrom = new Date(currentRecSec.activeFrom.year,currentRecSec.activeFrom.month,currentRecSec.activeFrom.day ...

Typescript compiler still processing lib files despite setting 'skipLibCheck' to true

Currently, I am working on a project that involves a monorepo with two workspaces (api and frontEnd). Recently, there was an upgrade from Node V10 to V16, and the migration process is almost complete. While I am able to run it locally, I am facing issues w ...

The variable 'module' is required to be of type 'any', but it is currently identified as type 'NodeModule'

I am currently working on a project using Angular and have just installed version 1.0.5 of ng2-dropdown-treeview. After installation, I restarted my server by running npm start. Upon checking the server log, I encountered the following error message: [PA ...

How can you make sure that VS Code always utilizes relative paths for auto imports in TypeScript?

VS Code has been automatically importing everything using Node-like non-relative paths relative to baseUrl, which is not the desired behavior. Is there a way to instruct VS Code to import everything with relative paths, excluding Node modules? Removing t ...

Spacing Problem with Title Tooltips

After using the padEnd method to ensure equal spacing for the string and binding in the title, I noticed that the console displayed the string perfectly aligned with spaces, but the binded title appeared different. Is it possible for the title to support s ...

Is it possible for object destructuring in Javascript to include dynamic non-rest keys using ...rest?

Suppose we have an object: const obj = { key1: "value1", key2: "value2", key3: "value3", key4: "value4" }; My goal is to filter out specific keys from this object to create a smaller one. I am aware of the following ...

merging JavaScript objects with complex conditions

I am attempting to combine data from two http requests into a single object based on specific conditions. Take a look at the following objects: vehicles: [ { vId: 1, color: 'green', passengers: [ { name: 'Joe', ag ...

What is the designation of an iterator?

I have the ability to create my own generator function that returns a Generator. The type for this can be specified as type Iterable = { [Symbol.iterator](): Generator };, although it is not valid for standard built-in types like Array. This limitation may ...

Retrieve information from Firebase outside of the .on() method

As a newcomer to Typescript, I am struggling to understand how to access the variables latitude1 and latitude2 outside of the this.ref.on('value', (snapshot) function in order to add their values to the locations array. Can anyone provide some gu ...

Setting default values for multiple selections can be accomplished by following these steps

I am working on a form that collects information about streets and their corresponding neighborhoods: https://i.sstatic.net/FAZLK.png When I click on a button in the grid to edit, the street data is displayed like this: https://i.sstatic.net/UHiLX.png ...

What is the reason behind TypeScript failing to provide type safety in a generic higher order component which introduces extra properties into React components?

I'm currently working on developing a versatile higher order component, but have encountered an issue with type safety not being enforced. Interestingly, when attempting the same implementation without using generics, the type safety is verified as ex ...

I'm encountering an error when trying to use makeStyles

Something seems off with MUI. I was working on my project yesterday and makeStyles was functioning properly, but now it's suddenly stopped working. I'm encountering an error when calling it here: https://i.sstatic.net/tBf1I.png I suspect the iss ...

Ensure that at least one of two props is mandatory in a functional component while using typescript

Consider a scenario where we have a functional component: // my-component.tsx interface Props { propA?: string; propB?: number; } const MyComponent = ({propA, propB}: Props) => { return <div>Hello world</div> } Now, let's incorp ...

What is the best method for inserting content into a custom element as input for the component?

Currently, I am in the process of creating a syntax highlighting web component that will be able to highlight any content placed inside it. Let me illustrate with an example code snippet: <fs-highlight data-line-numbers="true" data-language=&q ...

Utilizing sourcemaps in ionic for seamless linking

I've encountered an issue with source maps or a similar feature. After inserting console.log(...) in my code, the message appears in the console but links to the compiled JavaScript file instead of the original TypeScript file. Have I overlooked som ...

Tips for designating the category of factory objects

Operating under a model view architecture, my goal is to generate a view object using a model object. Below is a simple illustration. What is the best way to specify the type of my model objects: should I use enums (albeit not easily extendable) or intege ...

After inputting new values, the table is not allowing me to update it

Recently acquainted with Angular, I am in the process of inserting new values and displaying them in a table using three components. These components include one for listing user information user-list, one for creating information rows user-form, and one f ...