在 Typescript 中将静态导入转换为动态导入
Convert static to dynamic import in Typescript
我有一个用 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)
}
}
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
理解为 函数 的引用仍然有点令人困惑而不是 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)
}
我有一个用 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)
}
}
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
理解为 函数 的引用仍然有点令人困惑而不是 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)
}