TypeScript var 与导入
Posted
技术标签:
【中文标题】TypeScript var 与导入【英文标题】:TypeScript var vs import 【发布时间】:2015-07-03 18:45:23 【问题描述】:在TypeScript中,有什么区别
import http = require('http');
和
var http = require('http');
我看到这两种方式都在代码源中使用,它们可以互换吗?
【问题讨论】:
第一个对我来说无效? 你的意思是import http from 'http'
可能吗?前者是 ES6 模块导入声明,后者是 CommonJS 模块导入。
@adeneo,第一个是由 Visual Studio 使用他们的 Typescript + node.js 插件自动生成的
好的,但这仍然不是 javascript,可能是 Typescript。在 javascript 中,就像 Felix 上面写的那样,要么是 ES6 import stuff from module
,要么是 Node 中使用的 commonJS 版本,带有一个常规变量和对 require()
的调用
【参考方案1】:
您的 import
语句是 TypeScript,不会在 Node.js 中按原样运行。您需要先将其编译(转译?)为 JavaScript。您可以阅读 TypeScript 文档以了解有关 TypeScript import
关键字如何工作的更多信息。请参阅"Using Modules" subsection of the "Namespaces and Modules" section of the TypeScript handbook。
在 JavaScript 中也有一个 import
关键字,但它不像 TypeScript 的 import
那样工作。它仅适用于支持 ES6 模块的 Node 版本。 import
和 require
之间存在差异,您可以在 "ES6 Modules: The Final Syntax" 阅读。 import
是您可以与 require
比较/对比的东西,但不是真正的 var
。
【讨论】:
这如何回答这个问题?信息很有趣,但不是答案。 @viscanner 该问题随后被编辑以添加“TypeScript”(原始问题中没有)。然后 在发布此答案 8 个月后,再次对其进行编辑以删除“Node.js”,从而使此答案出现无效。此答案解决了撰写此答案时出现的问题。 @Trott,MS 已删除您提供的名为“Going External”的链接。我翻阅了他们的新 github 文档,但找不到该页面。您是否有机会找到它并在您的答案中而不是链接中快速了解它? @bgura TypeScript 和 Node.js 发生了很大变化,但相关部分已重命名为“使用模块”,可以在 typescriptlang.org/docs/handbook/… 找到。我会更新答案。【参考方案2】:我也有同样的询问。刚刚在 Typescript 的“别名”部分找到了这个:
这类似于使用 var,但也适用于导入符号的类型和命名空间含义。重要的是,对于值,导入是与原始符号不同的引用,因此对别名变量的更改不会反映在原始变量中
https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases
【讨论】:
这是主要区别。如果我们使用 var ,它似乎是通过引用传递的。在英语中,这意味着(根据我的理解,如果我错了,请纠正我)你分配给 var 的对象发生的任何更改,即使你没有重新分配它也会改变。而使用 import 将创建它的独立副本。【参考方案3】:TypeScript import
关键字有多种用法,其中一些取决于环境,解释了为什么它会令人困惑。让我们看看最小细节级别(因为在实际项目中它可能更复杂):
模块 CommonJs / 节点
@mfc:这与您的问题相对应。
TypeScript 项目使用 CommonJs 模块,通常是节点项目:
// tsconfig.json
"compilerOptions":
"module": "commonjs",
...
在这种情况下,import _ = require('http');
(版本#1)被转换为var _ = require('http');
(版本#2)。所以版本 #1 是 TypeScript 语法,而版本 #2 是 JavaScript 语法。
require()
在版本 1 中受支持,但在版本 #2 中不支持(错误[ts] Cannot find name 'require'.
),除非通过npm i @types/node --save-dev
将节点类型添加到项目中(请参阅此*** Q/A)。
模块 ES6
@mfc:这不是你要求的情况。但它在Trott's answer 中,所以我已将其考虑在内。
import
是 ES6 关键字并且有它的 own syntax:
import * as lib from 'lib';
命名导出的“选择”导入:import square, diag from 'lib';
默认导出的导入:import myFunc from 'myFunc';
根据上面提到的模块编译器选项,这些导入的转译方式不同:
ES6
→ 没有变化
CommonJS
→ var ... = require('...');
AMD
→ define(...);
命名空间
别名
@mfc:这不是你要求的情况。但它在Jose A's answer,所以我在这里添加了完整的图片。
在以前称为“(内部)模块”的namespace
中,import
用于创建alias,这是另一个命名空间的导出元素的快捷方式。
namespace Root.Branch.Leaf
export const configPath = '...';
namespace LeafClient
import configPath = Root.Branch.Leaf.configPath;
console.log(`configPath=$configPath`);
import configPath = Root.Branch.Leaf.configPath;
行被转换成var configPath = Root.Branch.Leaf.configPath;
,参见。 TypeScript PlayGround.
注意命名空间之外的用法,因为它创建了全局变量!
全局模块
有些库会修改全局对象(浏览器中的window
全局变量),例如:
$
全局变量,
reflect-metadata 扩展为 Reflect
。
ES6 语法还允许使用 side effects only import 加载此类库:import "reflect-metadata";
TypeScript 支持这个kind of imports。编译器将尝试获取相应的typing definition 以了解库效果,例如新方法Reflect.getMetadata()
。
【讨论】:
以上是关于TypeScript var 与导入的主要内容,如果未能解决你的问题,请参考以下文章
用于导入类型的 Eslint typescript no-unused-vars 触发器
要求语句不是导入语句的一部分。eslint@typescript-eslint/no-var-需要从存储中导入打字稿
Chutzpah - 使用 jasmine 和 TypeScript 进行 AngularJS 测试