typescript - 以 ES6 为目标时 Typescript 中的外部模块

标签 typescript ecmascript-6 koa es6-module-loader koa2

随着 Typescript 1.7 和 async/await 支持的发布,我认为现在是用 koa@2 试用 Typescript 的好时机。

我有一个非常简单的设置,它已经可以正常工作了:

// app.ts

/// <reference path="../typings/koa.d.ts" />

import Koa from 'koa';

const app = new Koa();

因为 koa 不是用 Typescript 写的,所以我不得不做一个小的定义文件:

// koa.d.ts
declare module 'koa' {

  interface Context {
    // ctx
  }

  export default class Koa {
    constructor();

    listen(port: number): any;
    use(Function: (ctx: Context, next: () => Promise<void>) => void): Function;
    use(Function: (ctx: Context) => void): Function;
  }
}

这一切在 IDE 中运行良好(没有错误,自动完成也可以)。但是,当我将它编译 (target => ES6) 为 Javascript 时,编译后的文件无法执行:

// generated app.js
var koa_1 = require('koa');
const app = new koa_1.default();

当我尝试运行它时,出现以下错误:

/Users/andreas/IdeaProjects/project/dist/app.js:16
const app = new koa_1.default();
            ^

TypeError: koa_1.default is not a function
    at Object.<anonymous> (/Users/andreas/IdeaProjects/project/dist/app.js:16:13)
    at Module._compile (module.js:425:26)
    at Object.Module._extensions..js (module.js:432:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:313:12)
    at Function.Module.runMain (module.js:457:10)
    at startup (node.js:138:18)
    at node.js:974:3

它不起作用,因为 koa_1.default() 不是一个函数,它应该只是 koa_1()。 (我也不确定为什么它会这样重命名变量)。如果我在生成的 app.js 中进行这个简单的更改,一切正常。

我正在阅读许多与 typescript 和外部模块相关的文章,但我似乎仍然遗漏了一些东西。我在其中一个网站上找到了这个例子:source

// foo.js
export var bar = 'bar'  
export default 'foo';

// app.js
import foo from './foo';  
// foo => 'foo'
import * as fooModule from './foo';  
// fooModule => { bar: 'bar', default: 'foo' }
import { default as defaultFoo } from './foo';  
// defaultFoo => 'foo'

这解释了为什么要添加 .default,但根据我的理解,它是在错误的情况下添加的。 (当我 import Koa from 'koa'; 时不需要,但是当我 import * as Koa from 'koa';

当我将 app.ts 中的导入语句更改为 import * as Koa from 'koa'; 时,生成的 app.js 可以正常工作,但 Typescript 编译器和 IDE 会出现以下错误。

src/app.ts(13,13): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
src/app.ts(23,16): error TS7006: Parameter 'ctx' implicitly has an 'any' type.
src/app.ts(23,21): error TS7006: Parameter 'next' implicitly has an 'any' type.
src/app.ts(32,9): error TS7006: Parameter 'ctx' implicitly has an 'any' type.

所以目前,我可以选择我的开发环境是否有效,或者生成的 Javascript 是否有效,但不能同时选择两者。

处理这个问题的最佳方法是什么?

我认为最简单的方法是更改​​ koa.d.ts 定义文件以匹配 import * as Koa from 'koa';。但是,我没有做到这一点。

感谢您的帮助!

最佳答案

改变这个:

 export default class Koa {

对此

class Koa {
// ...
namespace Koa { // add all your export interface inside
// ...
export = Koa;

继续使用 import * as Koa 语法。

关于typescript - 以 ES6 为目标时 Typescript 中的外部模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34192366/

相关文章:

javascript - React 无法读取未定义的属性映射

node.js - koa中独立的路由器和 Controller

javascript - 如何使用 Angular Material 在下拉列表中创建 TreeView ?

angular - Angular 6 'pdf-viewer' 的 ng2-pdf-viewer 不是已知对象

javascript - 使用 Javascript 调整图像大小而不在 DOM 上渲染 Canvas

javascript - 无法理解 Node.js 中的错误

javascript - 如何摆脱 koa-router 添加的未定义的 "phantom"路由

javascript - 在 TypeScript 中使用不同参数类型覆盖函数的正确方法

javascript - 获取 polyfill 在 Edge(或 IE)上不起作用

javascript - (中间值).then 不是函数