无法重新声明块作用域变量(打字稿)


98

我正在构建一个节点应用程序,并在.js文件中的每个文件内使用了此程序,以在各种软件包中进行此操作。

let co = require("co");

但是得到

在此处输入图片说明

等等。因此,使用打字稿似乎在整个项目中只能有一个这样的声明/要求?我对此感到困惑,因为我认为let范围仅限于当前文件。

我刚刚有一个正在运行的项目,但是经过重构之后,到处都是这些错误。

有人可以解释吗?


1
怎么样-让co_module = require(“ co”); 我遇到了类似的问题,这解决了错误。
tyrion '16

1
这似乎是一个打字稿错误。我在这里做了一个最小的示例:gist.github.com/rjmunro/428ec644b6e53a499ca3a5ba8de2edc7
rjmunro

5
2.5年后,我回到自己的问题上,这仍然是一个问题。这次使用内置的节点。const fs = require('fs')给出类似的错误,所以不确定从哪个库导入...
dcsan

事实上TS仍然如此,这是荒谬的
GN。

Answers:


67

关于错误本身,let用于声明存在于块作用域而不是函数作用域中的局部变量。它也比严格,因此您不能执行以下操作:var

if (condition) {
    let a = 1;
    ...
    let a = 2;
}

还要注意,块case内的子句switch不会创建自己的块作用域,因此您不能跨多个cases重新声明相同的局部变量,而无需使用{}每个块来创建块。


至于导入,您可能会遇到此错误,因为TypeScript无法将文件识别为实际模块,并且看来模型级定义最终是该文件的全局定义。

尝试以标准ES6方式导入外部模块,该模块不包含任何显式分配,并且应使TypeScript正确将文件识别为模块:

import * as co from "./co"

如果您co已经按预期命名,则仍然会导致编译错误。例如,这将是一个错误:

import * as co from "./co"; // Error: import definition conflicts with local definition
let co = 1;

如果出现错误“找不到模块合作伙伴”,则...

TypeScript正在针对模块运行完整的类型检查,因此,如果您没有要导入的模块的TS定义(例如,因为它是不带定义文件的JS模块),则可以在不包含定义文件的定义文件中声明模块.d.ts不包含模块级导出:

declare module "co" {
    declare var co: any;
    export = co;
}

9
这给出了“找不到模块co”。我也试过typings install coUnable to find "co" in the registry。还有其他想法吗?
dcsan

我遇到了与@dcsan相同的问题,它说即使我清楚地安装了npm也找不到模块。
justin.m.chase

它可能是由相对路径引起的。我不熟悉NodeJS模块管理,但是在RequireJS中,如果相对引用了模块,则必须明确表示当前文件夹。也就是说,./co代替co,如果是co.ts在同一文件夹(或编译后的输出,co.js)。
约翰·威茨

1
注意,“ *为xxx”很重要。因此,不是“从...导入xxx”,而是“从...导入xxx”
Nurbol Alpysbayev

27

我能得到的最好的解释是Tamas Piro的帖子

TLDR;TypeScript将DOM类型用于全局执行环境。在您的情况下,全局窗口对象上有一个'co'属性。

要解决这个问题:

  1. 重命名变量,或者
  2. 使用TypeScript模块,并添加一个空的export {}:
export {};

要么

  1. 通过不添加DOM类型来配置编译器选项:

在TypeScript项目目录中编辑tsconfig.json。

{
    "compilerOptions": {
        "lib": ["es6"]
      }
}

这是给客户端的吗?我最初的问题是服务器端代码,我不相信使用了DOM编译器选项(旧项目)
dcsan

1
我确认添加export {}确实解决了我的问题,但是"compilerOptions": { "lib": ["es6"] }在VSCode中编译和添加时似乎都没有帮助。
adamsfamily

原始帖子的链接已失效。
Cyclonecode

13

编译Node.JS Typescript应用程序时收到以下类似错误:

node_modules/@types/node/index.d.ts:83:15 - error TS2451: Cannot redeclare block-scoped variable 'custom'.

解决方法是删除此:

"files": [
  "./node_modules/@types/node/index.d.ts"
]

并替换为:

"compilerOptions": {
  "types": ["node"]
}

9

使用IIFE(Immediately Invoked Function Expression)IIFE

(function () {
    all your code is here...

 })();

简单。完美运作。谢谢!(就我而言,我声明const expect = chai.expect;要在Angular 5项目中使用Cucumber测试)。
Maxime Lafarie '18


1

我遇到了同样的问题,我的解决方案如下所示:

// *./module1/module1.ts*
export module Module1 {
    export class Module1{
        greating(){ return 'hey from Module1'}
    }
}


// *./module2/module2.ts*
import {Module1} from './../module1/module1';

export module Module2{
    export class Module2{
        greating(){
            let m1 = new Module1.Module1()
            return 'hey from Module2 + and from loaded Model1: '+ m1.greating();
        }
    }
}

现在我们可以在服务器端使用它:

// *./server.ts*
/// <reference path="./typings/node/node.d.ts"/>
import {Module2} from './module2/module2';

export module Server {
    export class Server{
        greating(){
            let m2 = new Module2.Module2();
            return "hello from server & loaded modules: " + m2.greating();
        }
    }
}

exports.Server = Server;

// ./app.js
var Server = require('./server').Server.Server;
var server = new Server();
console.log(server.greating());

在客户端也是如此:

// *./public/javscripts/index/index.ts*

import {Module2} from './../../../module2/module2';

document.body.onload = function(){
    let m2 = new Module2.Module2();
    alert(m2.greating());
}

// ./views/index.jade
extends layout

block content
  h1= title
  p Welcome to #{title}
  script(src='main.js')
  //
    the main.js-file created by gulp-task 'browserify' below in the gulpfile.js

并且,当然,这是所有的gulp文件:

// *./gulpfile.js*
var gulp = require('gulp'),
    ts = require('gulp-typescript'),
    runSequence = require('run-sequence'),
    browserify = require('gulp-browserify'),
    rename = require('gulp-rename');

gulp.task('default', function(callback) {

    gulp.task('ts1', function() {
        return gulp.src(['./module1/module1.ts'])
            .pipe(ts())
            .pipe(gulp.dest('./module1'))
    });

    gulp.task('ts2', function() {
        return gulp.src(['./module2/module2.ts'])
            .pipe(ts())
            .pipe(gulp.dest('./module2'))
    });

    gulp.task('ts3', function() {
        return gulp.src(['./public/javascripts/index/index.ts'])
            .pipe(ts())
            .pipe(gulp.dest('./public/javascripts/index'))
    });

    gulp.task('browserify', function() {
        return gulp.src('./public/javascripts/index/index.js', { read: false })
            .pipe(browserify({
                insertGlobals: true
            }))
            .pipe(rename('main.js'))
            .pipe(gulp.dest('./public/javascripts/'))
    });

    runSequence('ts1', 'ts2', 'ts3', 'browserify', callback);
})

更新。 当然,不必分别编译打字稿文件。 runSequence(['ts1', 'ts2', 'ts3'], 'browserify', callback)完美的作品。


7
万一有人因该gulp文件的冗长和重复性而将TypeScript拒之门外,没有人这样做。
Daniel Earwicker

0

升级时出现此错误

gulp-typescript 3.0.2→3.1.0

将其放回3.0.2,将其修复


0

就我而言,以下tsconfig.json解决了问题:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "target": "ES2020",
    "moduleResolution": "node"
  }
}

不应有typemodulepackage.json

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.