我有一个用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)
}
}
答案 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)
}