Преобразование статического в динамический импорт в Typescript - PullRequest
0 голосов
/ 02 июля 2019

У меня есть приложение Express.js, написанное на TypeScript (2.7.1), и я пытаюсь динамически импортировать модуль 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 голосов
/ 02 июля 2019

Функция 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 как ссылку на функция , а не как пространство имен ), и это приводит к решению:

  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)
    }
...