【问题标题】:How can I use a @types which is a Module from a TypeScript file which is not a Module?如何使用不是模块的 TypeScript 文件中的模块 @types?
【发布时间】:2020-04-08 15:08:31
【问题描述】:

背景:

我正在将大约 3,000 个内联 <script> 从网页转换为 TypeScript 文件 (PageScripts.ts),然后页面将使用该文件作为 <script src="PageScripts.js" defer></script>

该脚本使用具有a @types package available 的 SortableJS。 *.d.ts 文件在 GitHub 上可用:https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/sortablejs

原脚本:

以下是 HTML 页面中导致问题的原始 JavaScript 部分:

<script type="text/javascript">

window.addEventListener( 'DOMContentLoaded', function() {

    var sortableOptions = {
        dataIdAttr: 'my-id',
        onEnd: function( ev ) {

            // do stuff
        }
    };

} );

</script>

我通过运行npm install --save @types/sortablejs 添加了@types。

我的tsconfig.json 看起来像这样:

  {
        "compileOnSave": true,
        "compilerOptions": {
            "noImplicitAny": true,
            "strict": true,
            "noEmitOnError": true,
            "removeComments": true,
            "sourceMap": true,
            "target": "es5" /* es5 for IE11 support. */,
            "typeRoots": [
                "node_modules/@types",
                "JSFiles/System.Web.dll/Types"
            ],
            "lib": [
                "es5",
                "dom",
                "dom.iterable",
                "es2015.core",
                "es2015.collection",
                "es2015.symbol",
                "es2015.iterable",
                "es2015.promise"
            ]
        },
        "exclude": [
            "node_modules"
        ]
    }

打字稿:

我在PageScripts.ts中将上面的脚本片段转换成这个TypeScript:

import Sortable = require("sortablejs");

// ...

window.addEventListener( 'DOMContentLoaded', function() {

    var sortableOptions = {
        dataIdAttr: 'my-id',
        onEnd: function( ev: Sortable.SortableEvent ) {

            // do stuff
        }
    };

} );

这编译没有任何错误,但是因为 TypeScript 文件有一个 import 语句,它会导致 TypeScript 将文件编译到它自己的 JavaScript 模块,这意味着它不能被网页直接使用,因为 TypeScript 将它添加到输出PageScripts.js文件的开头:

Object.defineProperty(exports, "__esModule", { value: true });

...这会导致浏览器脚本错误,因为 exports 未定义。

所以我将其改为使用/// &lt;reference types=/&gt;

/// <reference types="sortablejs" />

// ...

window.addEventListener( 'DOMContentLoaded', function() {

    var sortableOptions = {
        dataIdAttr: 'my-id',
        onEnd: function( ev: Sortable.SortableEvent ) {        <--- "Cannot find namespace 'Sortable'."

            // do stuff
        }
    };

} );

但现在PageScripts.ts 无法编译,因为tsc 抱怨它“找不到命名空间'Sortable'。”

IDE 代码修复菜单说修复是添加一个 import Sortable = require("sortablejs") 行 - 但这意味着我的 PageScripts.js 文件又是一个模块,啊!

我也无法在我的tsconfig.json 中设置module: 'none',因为我的项目中有其他TypeScript 文件是 模块,我不想通过更改全局设置来影响它们。是否有每个文件的模块设置或任何东西?

问题:

那么 - 我怎样才能使用来自 @types/sortablejs 的类型而不导致我的 PageScripts.js 文件成为一个模块?

【问题讨论】:

  • 您是否尝试过添加另一个具有适当设置的 tsconfig 文件?
  • @AlekseyL。另一个 tsconfig 文件有什么帮助?您指的是什么“适当的设置”?我正在使用 TypeScript 来编译和生成全局脚本,以用于返回 IE11 的网络浏览器,所以我根本无法使用模块。
  • 我也无法在我的 tsconfig.json 中设置 module: 'none' 你说的是这个
  • @AlekseyL。设置module: "none" 会因为不相关的原因破坏我项目中的其他文件。
  • 这就是为什么你需要为这个特定文件单独配置

标签: javascript typescript


【解决方案1】:

尝试将sortablejs d.ts 文件添加到tsconfig.json 文件中的includes 数组中,这将使该库全局可用。

【讨论】:

    猜你喜欢
    • 2019-01-04
    • 1970-01-01
    • 2018-12-07
    • 2015-12-24
    • 1970-01-01
    • 2020-01-18
    • 2022-12-16
    • 2017-11-09
    • 2017-11-23
    相关资源
    最近更新 更多