cannot redeclare block scoped variable (typescript

2019-02-07 15:58发布

I'm building a node app, and inside each file in .js used to doing this to require in various packages.

let co = require("co");

But getting

enter image description here

etc. So using typescript it seems there can only be one such declaration/require across the whole project? I'm confused about this as I thought let was scoped to the current file.

I just had a project that was working but after a refactor am now getting these errors all over the place.

Can someone explain?

5条回答
我欲成王,谁敢阻挡
2楼-- · 2019-02-07 16:32

I got this error when upgrading

gulp-typescript 3.0.2 → 3.1.0

Putting it back to 3.0.2 fixed it

查看更多
虎瘦雄心在
3楼-- · 2019-02-07 16:34

Use IIFE(Immediately Invoked Function Expression), IIFE

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

 })();
查看更多
一纸荒年 Trace。
4楼-- · 2019-02-07 16:40

I got the same problem, and my solution looks like this:

// *./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();
        }
    }
}

Now we can use it on the server side:

// *./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());

And on the client side too:

// *./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

And, of course, a gulp-file for all of this:

// *./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);
})

Updated. Of course, it's not neccessary to compile typescript files separatly. runSequence(['ts1', 'ts2', 'ts3'], 'browserify', callback) works perfect.

查看更多
beautiful°
5楼-- · 2019-02-07 16:48

The best explanation I could get is from Tamas Piro's post.

TLDR; TypeScript uses the DOM typings for the global execution environment. In your case there is a 'co' property on the global window object.

To solve this:

  1. Rename the variable, or
  2. Use TypeScript modules, and add an empty export{}:
export{};

or

  1. Configure your compiler options by not adding DOM typings:

Edit tsconfig.json in the TypeScript project directory.

{
    "compilerOptions": {
        "lib": ["es6"]
      }
}
查看更多
Emotional °昔
6楼-- · 2019-02-07 16:51

let is used to declare local variables that exist in block scopes instead of function scopes.

The latest preferred way of importing an external module is the ES6 syntax anyways, which contains no explicit assignment:

import * as co from "./co"
查看更多
登录 后发表回答