Applying TypeScript definitions to an NPM module using function prototypes

Help needed with TypeScript and old-school JavaScript

I’m working on a project where I need to use this old npm package. It’s built with function prototypes, which is making it tricky to add TypeScript support.

Here’s what the package looks like:

function Human(name) {
  this.name = name
}

Human.prototype.yell = function() {
  console.log(this.name + ': Woohoo!')
}

module.export = Human

I’ve tried to create a type definition file, but it’s not working:

declare module 'humans' {
  interface Human {
    new(name: string): Human;
    readonly yell: () => void;
  }

  export = Human;
}

When I try to use it like this:

import Human from 'humans';

const human = new Human('Jane');
human.yell()

I get an error saying Human is just a type, not a value. I’m pretty lost here. How do I make TypeScript play nice with this old-school JavaScript? Also, am I importing it right? Any tips would be awesome!

As someone who’s been in the trenches with TypeScript and legacy JS, I feel your pain. Here’s a trick I’ve found that works well:

Instead of using declare module, try using a global declaration file. Create a file named humans.d.ts in your project root and add this:

declare class Human {
  constructor(name: string);
  name: string;
  yell(): void;
}

export = Human;

This approach has saved me countless headaches when dealing with old-school JS libraries. It tells TypeScript exactly what to expect without messing with the original module structure.

For importing, your current method should work fine. Just make sure your tsconfig.json is set up to recognize declaration files.

Hope this helps! Let me know if you run into any other snags.

I’ve encountered similar issues when working with legacy JavaScript modules. Your approach is close, but there’s a slight adjustment needed in the type definition. Instead of using an interface, declare Human as a class constructor. This aligns better with the prototype-based structure of the original module.

Here’s a modified version that should resolve your TypeScript errors:

declare module 'humans' {
  class Human {
    constructor(name: string);
    name: string;
    yell(): void;
  }
  export = Human;
}

This declaration accurately represents the structure of the JavaScript module, allowing TypeScript to properly type-check your usage. The export syntax you’re using is correct for CommonJS-style modules. With this definition, your import and usage should work as expected without any type errors.

hey jack, i’ve dealt with this before. for your type def, try:

declare module 'humans' {
  class Human {
    constructor(name: string);
    yell(): void;
  }
  export = Human;
}

this should work with your import. lemme know if u need more help!