在Typescript中将静态转换为动态导入

时间:2019-07-02 16:28:40

标签: typescript express typescript2.0 express-session

我有一个用TypeScript(2.7.1)编写的Express.js应用程序,并且我正在尝试动态导入express-session模块。以我的理解,import session from 'express-session'应该等效于let session = await import('express-session'),但是静态导入可以很好地工作(如果安装了express-session,而动态版本则可以:

error TS2349: Cannot invoke an expression whose type lacks a call signature. 
Type '{ default: typeof session; Store: typeof Store; MemoryStore: typeof MemoryStore; }' 
has no compatible call signatures

这是删除静态导入并用try-catch包围导入后我的文件的样子:

import express from 'express'

export class MyServer {
  public app: express.Application

  constructor() {
    this.app = express()
    this.init()
  }

  async init() {
    try {

      const session = await import('express-session')

      this.app.use(session({secret: 'my_secure_secret'}))
      this.app.set('hasSession', true)
    } catch (e) {
      console.log('Failed to load session, continue without it')
      this.app.set('hasSession', false)
    }
  }

1 个答案:

答案 0 :(得分:0)

import()函数实际上确实导入了整个 CommonJS exports对象。检查@types/express-session中的类型,我们有:

[...]
declare function session(options?: session.SessionOptions): express.RequestHandler;

declare namespace session {
  interface SessionOptions {
    secret: string | string[];
    name?: string;
    store?: Store | MemoryStore;
    cookie?: express.CookieOptions;
    genid?(req: express.Request): string;
    rolling?: boolean;
    resave?: boolean;
    proxy?: boolean;
    saveUninitialized?: boolean;
    unset?: string;
  }
[...]
export = session;

在这一点上,export = session实际上等效于exports.default = session(仍然有些混淆,编译器将session理解为 function 的引用,而不是 > namespace ),这将导致解决方案:

  async init() {
    try {

      const session = (await import('express-session')).default

      this.app.use(session({secret: 'my_secure_secret'}))
      this.app.set('hasSession', true)
    } catch (e) {
      console.log('Failed to load session, continue without it')
      this.app.set('hasSession', false)
    }