Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A problem with the use of koa and typescript #1393

Closed
OLDIN opened this issue Jul 22, 2018 · 8 comments
Closed

A problem with the use of koa and typescript #1393

OLDIN opened this issue Jul 22, 2018 · 8 comments

Comments

@OLDIN
Copy link

OLDIN commented Jul 22, 2018

Hi, I have a problem using koa and typescript if set "esModuleInterop": true in tsconfig.json

My code and error:

screenshot at jul 22 14-21-38

My code:

import http from 'http';
import Koa from 'koa';
import bodyParser from 'koa-bodyparser';
import Router from 'koa-router';
import koalogger from 'koa-logger';
import helmet from 'koa-helmet';
import cors from 'kcors';

import logger from './logger.service';
import { AppRoutes } from "../routes";

import { ApolloServer, gql } from 'apollo-server-koa';

interface IRouter {
  [propName: string]: any
}

// Construct a schema, using GraphQL schema language
const typeDefs = gql`
  type Query {
    hello: String
  }
`;

// Provide resolver functions for your schema fields
const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
};

const graphqlServer: ApolloServer = new ApolloServer({ typeDefs, resolvers });

export async function createServer() {
  logger.info('Creating server...');
  const app = new Koa();
  const router = new Router();

  app.use(cors());
  app.use(helmet());
  app.use(koalogger());
  app.use(bodyParser());

  AppRoutes.forEach(route => (router as IRouter)[route.method](route.path, route.action));

  app.use(router.routes());
  app.use(router.allowedMethods());

  graphqlServer.applyMiddleware({ app });

  const server = http.createServer(app.callback());

  // Add a `close` event listener so we can clean up resources.
  server.on('close', () => {
    // You should tear down database connections, TCP connections, etc
    // here to make sure Jest's watch-mode some process management
    // tool does not release resources.
    logger.info('Server closing, bye!');
  });

  logger.info('Server created, ready to listen');

  return server;
}

My dependencies:

"koa": "^2.5.2",
"apollo-server-koa": "^2.0.0-rc.12", 
"@types/koa": "^2.0.46",
"typescript": "^2.9.1"
@martijnwalraven
Copy link
Contributor

martijnwalraven commented Jul 23, 2018

I have a problem using koa and typescript if set "esModuleInterop": true in tsconfig.json

Does that mean you don't see the error if you set "esModuleInterop": false?

@OLDIN
Copy link
Author

OLDIN commented Jul 23, 2018

@martijnwalraven

Does that mean you don't see the error if you set "esModuleInterop": false?

If to set "esModuleInterop": true that all works. But I spent half a day search for an error.
In the documentation there was nothing written.

Thanks for responding.

@OLDIN OLDIN closed this as completed Jul 23, 2018
@martijnwalraven
Copy link
Contributor

Yeah, that's still surprising to me, because I don't understand how "esModuleInterop" would affect typing here. So let's reopen the issue and see if we can find out more.

@OLDIN
Copy link
Author

OLDIN commented Jul 23, 2018

What additional information can I give you?

@jiripudil
Copy link

jiripudil commented Aug 9, 2018

Hi guys, I've stumbled upon the very same issue and did some research. It turns out that the esModuleInterop flag "changes the meaning of declaration" (microsoft/TypeScript#21535, particularly this comment, and also concisely explained at several places by the TS devs).

Long story short, since Koa is a commonjs module with export = Application in its type definitions, you cannot import * as Koa from 'koa' anymore and should instead use import Koa = require('koa'). A quick in-place replacement in node_modules shows that it works flawlessly, regardless of esModuleInterop settings.

@jiripudil
Copy link

Also, as a workaround until this is resolved in apollo-server packages, you can use type assertion. It's not even close to nice, but it does the job:

graphqlServer.applyMiddleware({ app: app as any });

@Nikki1993
Copy link

Nikki1993 commented Oct 9, 2018

Hm, seems to be still erroring out even though the change on apollo-server side was added to re-enable compatibility for esModuleInterop. #1699

@abernix
Copy link
Member

abernix commented Apr 26, 2019

Relates-to or duplicated-by #1977, #2519, #2521 (and more).

Thanks so much for opening this originally. While enabling esModuleInterop was more of a breaking change than intended (or even understood, at the time it was done), it's been almost a year now since it was first enabled. This flag first became available in TypeScript 2.7 and helps align TypeScript with the behavior chosen by Babel, Webpack, Rollup, React Native, etc. It's been the default configuration generated by tsc --init for quite some time and at this point we're intending to stick with esModuleInterop: true going forward.

@abernix abernix closed this as completed Apr 26, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants