如何将JS模块导入到TypeScript文件中?

162

我有一个 Protractor 项目,其中包含这样一个文件:

var FriendCard = function (card) {
    var webElement = card;
    var menuButton;
    var serialNumber;

    this.getAsWebElement = function () {
        return webElement;
    };

    this.clickMenuButton = function () {
        menuButton.click();
    };

    this.setSerialNumber = function (numberOfElements) {
        serialNumber = numberOfElements + 1;
        menuButton = element(by.xpath('.//*[@id=\'mCSB_2_container\']/li[' + serialNumber + ']/ng-include/div/div[2]/i'));
    };

    this.deleteFriend = function () {
        element(by.css('[ng-click="deleteFriend(person);"]')).click();
        element(by.css('[ng-click="confirm()"]')).click();
    }
};
module.exports = FriendCard;

文件路径为 ./pages/FriendCard.js

使用 require() 导入到另一个文件中没有问题:

var FriendCard = require('./../pages/FriendCard');

所以,我决定像这样将此文件导入 TypeScript 文件:

import {FriendCard} from './../pages/FriendCard'

我正在使用WebStorm。它告诉我(TS2305)没有导出成员'FriendCard'。

也许我需要以某种方式配置tsconfig.json文件,但我仍然不知道它的工作原理。 你能帮我吗?


1
我正在使用WebStorm,所以它告诉我(TS2305)它没有导出成员'FriendCard'。请注意,TS2305表示警告/错误是由实际的TypeScript编译器/语言服务产生的,而不是实际的WebStorm。因为IDE在自己的检查/解析器中不使用这样的编号。 - LazyOne
8个回答

184

您可以按照以下方式导入整个模块:

import * as FriendCard from './../pages/FriendCard';

有关详细信息,请参阅Typescript官方文档的模块部分。

最近更新的解决方案:我们需要调整tsconfig.json以允许JS模块导入。感谢下面@paulmest、@ben-winding和@crispen-gari的解决方案。

{
  "compilerOptions": {
    "allowJs": true
  }
}

6
感谢你在实际相对路径前面明确表达了“./”。这在编译时解析路径时非常关键。 - Roman
63
最新的吗?我还是遇到了相同的错误... 找不到模块的声明文件... - Nathan H
3
@nathan-h 你可能需要修改 tsconfig 文件... 更多信息请参见:https://dev59.com/xlgR5IYBdhLWcg3whtmk#56909179 - PaulMest

84

我目前正在对一些旧代码库进行改进,并引入最少量的TypeScript更改,以查看它是否有助于我们的团队。根据您对TypeScript的严格程度要求,这可能是可行的选项。

对我们来说最有用的方法是扩展我们的tsconfig.json文件,并加入以下属性:

// tsconfig.json excerpt:

{
  ...
  "compilerOptions": {
    ...
    "allowJs": true,
    ...
  }
  ...
}

这个更改允许拥有 JSDoc 类型提示的 JS 文件被编译,同时我们的 IDE(JetBrains IDE 和 VS Code)可以提供代码补全和智能感知。

参考资料:


2
我已经在 compilerOptions 中添加了以下内容 { "compilerOptions": { ..., "allowJs": true } ... } - Matheus Abreu
和我一样的使用情况,但是我认为这会使得迁移变得更加困难,因为你开始将所有遗留代码作为依赖项引入 TypeScript。 - Matthis Kohli

16

2021年解决方案

如果您仍然收到此错误信息:

TS7016: Could not find a declaration file for module './myjsfile'

那么您可能需要将以下内容添加到 tsconfig.json 中。

{
  "compilerOptions": {
    ...
    "allowJs": true,
    "checkJs": false,
    ...
  }
}

这样做可以防止 TypeScript 尝试将模块类型应用于导入的 JavaScript。


2
救命稻草!(记得重新启动你的编辑器) - Fernando Mellone
我发现这个解决方案适用于使用ts-jest的情况,在一个导入了一个.js文件,该文件又导入了一个.ts文件的.ts文件中。这是一个完全无法避免的情况,但有一个干净的解决方案。 - Lachlan McDonald

15

在你的第二个陈述中

import {FriendCard} from './../pages/FriendCard'

你正在告诉 TypeScript 从文件'./pages/FriendCard'中导入 FriendCard。

你的FriendCard文件正在导出一个变量,并且该变量引用了匿名函数。

这里有两个选项。如果您想以类型化的方式完成此操作,可以重构模块以进行类型化(选项1),或者导入匿名函数并添加d.ts文件。请参见 https://github.com/Microsoft/TypeScript/issues/3019 获取更多详细信息,了解为什么需要添加该文件。

选项1

将 Friend card js 文件重构为类型化。

export class FriendCard {
webElement: any;
menuButton: any;
serialNumber: any;

constructor(card) {
    this.webElement = card;
    this.menuButton;
    this.serialNumber;
}



getAsWebElement = function () {
    return this.webElement;
};

clickMenuButton = function () {
    this.menuButton.click();
};

setSerialNumber = function (numberOfElements) {
    this.serialNumber = numberOfElements + 1;
    this.menuButton = element(by.xpath('.//*[@id=\'mCSB_2_container\']/li[' + serialNumber + ']/ng-include/div/div[2]/i'));
};

deleteFriend = function () {
    element(by.css('[ng-click="deleteFriend(person);"]')).click();
    element(by.css('[ng-click="confirm()"]')).click();
}
};

选项2

您可以导入匿名函数

 import * as FriendCard from module("./FriendCardJs");

有几种选项可用于d.ts文件定义。此答案似乎最完整:如何从现有的JavaScript库生成.d.ts "typings"定义文件?


9

I tested 3 methods to do that...

Method1:

      const FriendCard:any = require('./../pages/FriendCard')

方法二:

      import * as FriendCard from './../pages/FriendCard';

方法3:

如果您在tsconfig.json中找到了以下内容:

      { "compilerOptions": { ..., "allowJs": true }

那么你可以写: import FriendCard from './../pages/FriendCard';

谢谢,方法一解决了我的问题,成功导入了一个js库。 - Jay

2

我一直面临这个问题很长时间了,但这解决了我的问题 进入 tsconfig.json 并在 compilerOptions 下添加以下内容:

{
  "compilerOptions": {
      ...
      "allowJs": true
      ...
  }
}

1

除了添加allowJs和checkJs之外,还有:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false
  }
}

请确保 strict 选项未设置为 true。


0

有关将allowJs:true添加到您的tsconfig.json 的答案对我很有帮助,但是我还必须确保tsconfig.json 中的includes: []块包括JavaScript文件。

{
  "compilerOptions": {
      ...
      "include": ["src/**/*.js"]
      ...
  }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接