draftbit / twitter-lite

A tiny, full-featured, flexible client / server library for the Twitter API
https://npm.im/twitter-lite
MIT License
794 stars 95 forks source link

Typescript warnings / runtime errors when using 'import' #111

Closed treylorswift closed 3 years ago

treylorswift commented 4 years ago

I'm not sure what the problem is but I had a hell of a time trying to integrate twitter-lite into a Typescript node.js project. I have figured out a work-around (jump to the bottom to see it) but want to document how the intuitive approaches to importing are currently failing. My first attempt:

import Twitter from 'twitter-lite';
let client = new Twitter({ .. init stuff here ..});

produced a run-time error like this:

TypeError: twitter_lite_1.default is not a constructor

So then I tried...

import {Twitter} from 'twitter-lite'

but that gets a compiler error:

error TS2305: Build:Module '"node_modules/twitter-lite/index"' has no exported member 'Twitter'.

So then I tried:

import * as Twitter from 'twitter-lite'
let client = new Twitter({ .. init stuff here ..});

this also gets a compiler error:

error TS2351: Build:Cannot use 'new' with an expression whose type lacks a call or construct signature.

I believe this is due to my import seeing 'Twitter' as a namespace, not a class. I get similar errors elsewhere when using 'Typescript' as a type on variable declarations. However if I ignore those warnings by adding a ts-ignore just above the lines where I use 'Twitter'...

import * as Twitter from 'twitter-lite'
//@ts-ignore
let client = new Twitter({ .. init stuff here ..});

If I do it this way, everything just works. But it does mean the TS compiler is effectively not doing any type-checking on the Twitter object (and, auto-complete in VisualStudio stops working). So there seems to be a problem somewhere.. perhaps the typescript definitions?

ghost commented 4 years ago

+1 Same problem

dylanirlbeck commented 4 years ago

I can imagine this would be rather frustrating -- I'm tagging @Fdebijl since he integrated TypeScript and might be able to identify a fix for this.

fdebijl commented 4 years ago

The main module exports a class, so the regular methods of importing a module in TS don't work in every case (which I had to learn the hard way).

The only way to import twitter-lite at this time with esModuleInterop disabled is const Twitter = require('twitter-lite'). If you have esModuleInterop enabled, you may also use the more natural import Twitter from 'twitter-lite', which also allows you to import typings like so: import Twitter, { AccessTokenOptions } from 'twitter-lite'.

Currently this is only explained at the top of index.d.ts, but we may have to include this explanation in the readme as well to prevent any confusion.