cannot redeclare block scoped variable (typescript)

后端 未结 8 1186
醉话见心
醉话见心 2020-12-08 18:02

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 gett

相关标签:
8条回答
  • 2020-12-08 18:29

    Regarding the error itself, let is used to declare local variables that exist in block scopes instead of function scopes. It's also more strict than var, so you can't do stuff like this:

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

    Also note that case clauses inside switch blocks don't create their own block scopes, so you can't redeclare the same local variable across multiple cases without using {} to create a block each.


    As for the import, you are probably getting this error because TypeScript doesn't recognize your files as actual modules, and seemingly model-level definitions end up being global definitions for it.

    Try importing an external module the standard ES6 way, which contains no explicit assignment, and should make TypeScript recognize your files correctly as modules:

    import * as co from "./co"
    

    This will still result in a compile error if you have something named co already, as expected. For example, this is going to be an error:

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

    If you are getting an error "cannot find module co"...

    TypeScript is running full type-checking against modules, so if you don't have TS definitions for the module you are trying to import (e.g. because it's a JS module without definition files), you can declare your module in a .d.ts definition file that doesn't contain module-level exports:

    declare module "co" {
        declare var co: any;
        export = co;
    }
    
    0 讨论(0)
  • 2020-12-08 18:30

    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.

    0 讨论(0)
  • 2020-12-08 18:33

    In my case the following tsconfig.json solved problem:

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

    There should be no type: module in package.json.

    0 讨论(0)
  • 2020-12-08 18:36

    Use IIFE(Immediately Invoked Function Expression), IIFE

    (function () {
        all your code is here...
    
     })();
    
    0 讨论(0)
  • 2020-12-08 18:37

    I was receiving this similar error when compiling my Node.JS Typescript application:

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

    The fix was to remove this:

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

    and to replace it with this:

    "compilerOptions": {
      "types": ["node"]
    }
    
    0 讨论(0)
  • 2020-12-08 18:41

    I got this error when upgrading

    gulp-typescript 3.0.2 → 3.1.0

    Putting it back to 3.0.2 fixed it

    0 讨论(0)
提交回复
热议问题