Blockbereichsvariable (Typoskript) kann nicht neu deklariert werden


89

Ich erstelle eine Knoten-App und bin in jeder Datei in .js daran gewöhnt, dies in verschiedenen Paketen zu erfordern.

let co = require("co");

Aber bekommen

Geben Sie hier die Bildbeschreibung ein

usw. Mit Typoskript scheint es also nur eine solche Deklaration / Anforderung für das gesamte Projekt zu geben? Ich bin darüber verwirrt, da ich dachte, dass letder Bereich auf die aktuelle Datei beschränkt ist.

Ich hatte gerade ein Projekt, das funktionierte, aber nach einem Refactor bekomme ich diese Fehler jetzt überall.

Kann jemand erklären?


1
Wie wäre es damit - lass co_module = require ("co"); Ich sah mich etwas Ähnlichem gegenüber und dies löste den Fehler.
Tyrion

1
Dies scheint ein Typoskript-Fehler zu sein. Ich habe hier ein minimales Beispiel gemacht: gist.github.com/rjmunro/428ec644b6e53a499ca3a5ba8de2edc7
rjmunro

4
2,5 Jahre später und ich bin wieder bei meiner eigenen Frage, das ist immer noch ein Problem. Diesmal mit eingebauten Knoten. const fs = require('fs')gibt einen ähnlichen Fehler, also nicht sicher, aus welcher Bibliothek dies importiert werden soll ...
dcsan

Antworten:


63

In Bezug auf den Fehler selbst werden lokale Variablen letdeklariert , die in Blockbereichen anstelle von Funktionsbereichen vorhanden sind. Es ist auch strenger als , also kann man so etwas nicht machen:var

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

Beachten Sie auch, dass caseKlauseln in switchBlöcken keine eigenen Blockbereiche erstellen, sodass Sie dieselbe lokale Variable nicht über mehrere cases hinweg neu deklarieren können, ohne {}jeweils einen Block zu erstellen.


Beim Import wird wahrscheinlich dieser Fehler angezeigt, da TypeScript Ihre Dateien nicht als tatsächliche Module erkennt und Definitionen auf Modellebene anscheinend globale Definitionen dafür sind.

Versuchen Sie, ein externes Modul auf die Standard- ES6- Methode zu importieren , die keine explizite Zuweisung enthält, und TypeScript sollte Ihre Dateien korrekt als Module erkennen:

import * as co from "./co"

Dies führt weiterhin zu einem Kompilierungsfehler, wenn Sie coerwartungsgemäß bereits einen Namen haben . Dies ist beispielsweise ein Fehler:

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

Wenn Sie die Fehlermeldung "Modul co kann nicht gefunden werden" erhalten ...

TypeScript führt eine vollständige Typprüfung für Module durch. Wenn Sie also keine TS-Definitionen für das Modul haben, das Sie importieren möchten (z. B. weil es sich um ein JS-Modul ohne Definitionsdateien handelt), können Sie Ihr Modul in einer Definitionsdatei deklarieren.d.ts , die dies nicht tut Enthält keine Exporte auf Modulebene:

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

9
Dies ergibt "Modul co kann nicht gefunden werden". Ich habe auch versucht typings install cowas gibt Unable to find "co" in the registry. irgendwelche anderen Ideen?
dcsan

Ich habe das gleiche Problem wie @dcsan, das besagt, dass das Modul nicht gefunden werden kann, obwohl ich es eindeutig npm installiert habe.
justin.m.chase

Dies kann durch den relativen Pfad verursacht werden. Ich bin nicht mit der NodeJS-Modulverwaltung vertraut, aber in RequireJS muss der aktuelle Ordner explizit angegeben werden, wenn auf Module relativ verwiesen wird. Das heißt, ./coanstatt codass sich co.ts im selben Ordner befindet (oder in der kompilierten Ausgabe, co.js).
John Weisz

1
Sei aufmerksam, "* as xxx" ist wichtig. Also nicht "xxx von ... importieren", sondern "als xxx von ... importieren"
Nurbol Alpysbayev

23

Die beste Erklärung, die ich bekommen konnte, ist von Tamas Piros Post .

TLDR; TypeScript verwendet die DOM-Typisierungen für die globale Ausführungsumgebung. In Ihrem Fall gibt es eine 'co'-Eigenschaft für das globale Fensterobjekt.

Um dies zu lösen:

  1. Benennen Sie die Variable um, oder
  2. Verwenden Sie TypeScript-Module und fügen Sie einen leeren Export hinzu {}:
export{};

oder

  1. Konfigurieren Sie Ihre Compileroptionen, indem Sie keine DOM-Typisierungen hinzufügen:

Bearbeiten Sie tsconfig.json im TypeScript-Projektverzeichnis.

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

Dies ist für den Kunden? Mein ursprüngliches Problem war mit serverseitigem Code und ich glaube nicht, dass die DOM-Compiler-Optionen verwendet wurden (altes Projekt)
dcsan

Ich bestätige, dass das Hinzufügen export {}das Problem für mich gelöst hat, aber das Hinzufügen "compilerOptions": { "lib": ["es6"] }scheint weder während der Kompilierung noch in VSCode zu helfen.
Adams Familie

12

Ich habe diesen ähnlichen Fehler beim Kompilieren meiner Node.JS Typescript-Anwendung erhalten:

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

Das Update bestand darin , Folgendes zu entfernen :

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

und um es durch dieses zu ersetzen:

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

7

Verwendung IIFE(Immediately Invoked Function Expression), IIFE

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

 })();

Einfach. Funktioniert perfekt. Danke dir! (In meinem Fall habe ich deklariert const expect = chai.expect;, um Gurkentests im Angular 5-Projekt zu verwenden).
Maxime Lafarie

3

Für diejenigen, die in dieser Zeit hierher kommen, ist hier eine einfache Lösung für dieses Problem. Zumindest hat es bei mir im Backend funktioniert. Ich habe den Frontend-Code nicht überprüft.

Einfach hinzufügen:

export {};

am Anfang Ihres Codes.

Gutschrift an EUGENE MURAVITSKY


1

Ich habe das gleiche Problem und meine Lösung sieht folgendermaßen aus:

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

Jetzt können wir es auf der Serverseite verwenden:

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

Und auch auf der Kundenseite:

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

Und natürlich eine Schluckdatei für all das:

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

Aktualisiert. Natürlich ist es nicht notwendig, Typoskriptdateien separat zu kompilieren. runSequence(['ts1', 'ts2', 'ts3'], 'browserify', callback)funktioniert perfekt.


6
Nur für den Fall, dass jemand durch die Ausführlichkeit und Wiederholbarkeit dieser Schluckdatei von TypeScript abgeschreckt wird, tut dies niemand.
Daniel Earwicker

0

Ich habe diesen Fehler beim Upgrade erhalten

gulp-typescript 3.0.2 → 3.1.0

Durch Zurücksetzen auf 3.0.2 wurde das Problem behoben

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.