interval-promise icon indicating copy to clipboard operation
interval-promise copied to clipboard

Can't import in typescript

Open lev-kuznetsov opened this issue 6 years ago • 5 comments

I don't know if this is continuation of #6

Documented way of importing in ts is

import interval from 'interval-promise'

Which expects the actual interval function to be on module.exports.default in the javascript world except it's on module.exports. Documented way of importing allows to compile since it's inline with the type file but doesn't work at runtime since module.exports.default is undefined. import * as interval from 'interval-promise' expectedly won't compile the function call unless you then cast:

import * as interval from 'interval-promise'

(<any>interval)(async () => console.log('hello world'), 5000)

Which obviously just bypasses the type file. What I think you want to put into the type file is:

declare module 'interval-promise' {
  interface IIntervalPromiseOptions {
    iterations?: number;
    stopOnError?: boolean;
  }

  type stop = () => void;
  type func = (iterationNumber: number, stop: stop) => Promise<void>;
  type intervalLengthFn = (iterationNumber: number) => void;
  type intervalLength = number | intervalLengthFn;
}

declare function interval(
  func: func,
  intervalLength: intervalLength, options?:
  IIntervalPromiseOptions): Promise<void>

export = interval

That way you'll be able to import via import * as interval from 'interval-promise' which is what you have to do because that's how it's documented for javascript. And this is inline with how the DefinitelyTyped guys do it here: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa-compose/index.d.ts

My tsconfig:

{
  "version": "2.9.2",
  "compilerOptions": {
    "lib": ["es5", "es6", "dom"],
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "target",
    "sourceMap": true
  },
  "exclude": [
    "node_modules",
    "target"
  ]
}

I can create a PR to this effect. Also might I suggest to allow func to return Promise<any> instead of Promise<void> - you don't really care what it returns as long as it's a promise, right?

lev-kuznetsov avatar Sep 25 '18 13:09 lev-kuznetsov

Hi @lev-kuznetsov. Thanks for the issue!

I'm planning on rewriting this library in TypeScript, so I will revisit this then.

andyfleming avatar Oct 09 '18 00:10 andyfleming

Still can't import this library with TypeScript

dguayrobotiq avatar Feb 01 '19 20:02 dguayrobotiq

A short-term alternative if you need one is to use the following syntax.

const interval = require('interval-promise')

andyfleming avatar Feb 01 '19 21:02 andyfleming

@andyfleming actually I rewrote the type file like so:

declare module 'interval-promise' {
  interface IIntervalPromiseOptions {
    iterations?: number;
    stopOnError?: boolean;
  }

  type stop = () => void;
  type func = (iterationNumber: number, stop: stop) => Promise<void>;
  type intervalLengthFn = (iterationNumber: number) => void;
  type intervalLength = number | intervalLengthFn;

  function interval(func: func,intervalLength: intervalLength, options?:IIntervalPromiseOptions): Promise<void>

  export = interval;
}

You really should consider updating the type file. I can make a quick PR if you're willing to merge it

dguayrobotiq avatar Feb 04 '19 13:02 dguayrobotiq

Using this just fine in TS 3.4 when giving the "esModuleInterop" compiler flag... and to be frank you're really shooting yourself in the foot in this day and age if you don't give that option.

favna avatar Apr 19 '19 07:04 favna