为啥在使用 Node.js 的许多文件中存在*** const 或 let 具有相同名称时,Typescript 会出错

Posted

技术标签:

【中文标题】为啥在使用 Node.js 的许多文件中存在*** const 或 let 具有相同名称时,Typescript 会出错【英文标题】:Why does Typescript error when there is a top level const or let with the same name in many files with Node.js为什么在使用 Node.js 的许多文件中存在*** const 或 let 具有相同名称时,Typescript 会出错 【发布时间】:2017-01-22 01:15:56 【问题描述】:

为什么在顶层声明 constlet 会导致 TS2451 错误(见下文)?我知道在浏览器中所有脚本都共享***范围,但我正在为 Node.js 编写所有 modules are wrapped。

此场景中的此错误是否与 Node.js 相关? 如果不能,是否可以将其配置掉/是我的问题吗? 为什么 var 不会出现同样的错误? var、const 和 let 的***作用域不是几乎相同吗?

a.ts

let lme = 'A';
const cme = 'A';
var me = 'a';

b.js

let lme = 'A';
const cme = 'A';
var me = 'a';

tsconfig.json


    "compilerOptions": 
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "sourceMap": false
    ,
    "exclude": [
        "node_modules"
    ]

输出

$ tsc
a.ts(3,5): error TS2451: Cannot redeclare block-scoped variable 'lme'.
a.ts(4,7): error TS2451: Cannot redeclare block-scoped variable 'cme'.
b.ts(3,5): error TS2451: Cannot redeclare block-scoped variable 'lme'.
b.ts(4,7): error TS2451: Cannot redeclare block-scoped variable 'cme'.

上下文

$ tsc --version
Version 1.8.10
$ node --version
v6.5.0

我最初是在尝试将多个文件从 .js 移植到 .ts 时遇到的,其中 const fs = require('fs');。我以为大多数基本的东西都可以在为 Node.js 编写的 tsjs 之间工作。

【问题讨论】:

您的a.ts 和'b.ts` 中有导入语句吗?否则它可能不会将其编译为模块。 @NitzanTomer 不,这些都是精简的例子。我不知道模块有不同的编译,呃,不是每个文件都是一个模块吗? 【参考方案1】:

编译器不会将您的 .ts 文件视为模块,除非文件中有(used)导入或导出。 因此,它抱怨重新声明变量。

例如:

const A = 3;

被编译成

var A = 3;

虽然

import * as Utils from "./utils"

const A = 3 * Utils.A;

被编译成

"use strict";
var Utils = require("./utils");
var A = 3 * Utils.A;

如果没有导入/导出,编译器不会将其视为模块。


编辑

你可以使用require语法,你只需要引用节点定义:

/// <reference path="./node.d.ts" />
const Utils = require("./utils")

【讨论】:

谢谢,但这似乎意味着 TS 不支持require 语法,这意味着从.js 移植到.ts 的所有文件都需要将require 替换为@987654332 @。这似乎很奇怪,因为无论如何它都被遵守require 这不正确,你可以使用require,查看我修改后的答案 好的是的,支持require(我用的是typings install env~node --global --save),但不会导致TS把文件当成模块,这很烦人。 什么意思?如果您使用const Utils = require("./utils"),它应该将您的文件编译为模块。 我看到了相同的行为,使用 require 确实 not 会导致文件被视为模块。在文件中添加export 确实会将其变成一个模块,因此可以为我修复它。使用打字稿 2.0.2。我想知道这是否取决于您对require 的类型,因为我只是在使用declare var require: any

以上是关于为啥在使用 Node.js 的许多文件中存在*** const 或 let 具有相同名称时,Typescript 会出错的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 node.js 中使用 sendFile() 方法为两个路由提供静态文件时会出错

为啥在 Node.js 中阻塞文件 I/O 时异步性能更差?

Node js ENOENT 文件错误处理

为啥 WebSocket 实现在传输多个文件时比 HTTP/2 Push 慢? (Node.js / 去)

Node.js - 编写了空文件,但为啥呢?

为啥在 Node.js 中使用猫鼬模式