blok kapsamlı değişkeni (typecript) yeniden bildirilemez


99

Bir düğüm uygulaması oluşturuyorum ve .js'deki her dosyanın içinde bunu çeşitli paketler gerektirmek için yapıyordum.

let co = require("co");

Ama almak

görüntü açıklamasını buraya girin

vb. Yani typcript kullanıldığında, tüm proje boyunca böyle bir beyan / gereksinim olabilir mi? letKapsamının mevcut dosya kapsamında olduğunu düşündüğüm için bu konuda kafam karıştı .

Daha yeni çalışan bir projem vardı ama bir refaktörden sonra şimdi her yerde bu hataları alıyorum.

Biri açıklayabilir mi?


1
Buna ne dersiniz - let co_module = required ("co"); Benzer bir şeyle karşılaştım ve bu hatayı çözdü.
tyrion

1
Bu bir daktilo hatası gibi görünüyor. Burada minimal bir örnek oluşturdum: gist.github.com/rjmunro/428ec644b6e53a499ca3a5ba8de2edc7
rjmunro

5
2,5 yıl sonra ve kendi soruma geri döndüm, bu hala bir sorun. bu kez yerleşik düğümlerle. const fs = require('fs')benzer bir hata veriyor, bu yüzden bunu hangi kitaplıktan içe
aktaracağınızdan

TS'nin bunu hala yaptığı gerçeği saçma
GN.

Yanıtlar:


67

Hatanın kendisi ile ilgili olarak, işlev kapsamları yerine blok kapsamlarında bulunan yerel değişkenleri letbildirmek için kullanılır . Ayrıca bundan daha katıdır , bu nedenle böyle şeyler yapamazsınız:var

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

Ayrıca, blokların caseiçindeki cümleciklerin switchkendi blok kapsamlarını oluşturmadığını, bu nedenle aynı yerel değişkeni, her birini bir blok oluşturmak için casekullanmadan birden çok s üzerinde yeniden açıklayamayacağınızı unutmayın {}.


İçe aktarma işlemine gelince, muhtemelen bu hatayı alıyorsunuz çünkü TypeScript dosyalarınızı gerçek modüller olarak tanımıyor ve görünüşte model düzeyindeki tanımlar bunun için küresel tanımlar oluyor.

Açık bir atama içermeyen ve TypeScript'in dosyalarınızı modüller olarak doğru bir şekilde tanımasını sağlayan standart ES6 yöntemiyle harici bir modülü içe aktarmayı deneyin :

import * as co from "./co"

coBeklendiği gibi, önceden adlandırılmış bir şeyiniz varsa bu yine de bir derleme hatasıyla sonuçlanacaktır . Örneğin, bu bir hata olacak:

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

"Modül co bulunamıyor" hatası alıyorsanız ...

Typescript tam tip denetimi çalıştıran modüllerin karşı, (bir JS modülü tanım dosyası olmayan çünkü örneğin) Eğer ithalat çalıştığınız modülü için TS tanımları yok eğer öyleyse, sen yapabilirsiniz beyan bir daki modül .d.tstanım dosyası olduğu doesn modül düzeyinde dışa aktarmalar içermez:

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

9
bu "co modülü bulunamıyor" verir. Ben de typings install cohangi verir denedim Unable to find "co" in the registry. başka fikir var mı?
dcsan

@Dcsan ile aynı sorunu yaşıyorum, açıkça npm kurulu olmasına rağmen modülü bulamadığını söylüyor.
justin.m.chase

Göreli yoldan kaynaklanıyor olabilir. NodeJS modül yönetimine aşina değilim, ancak RequireJS'de modüllere göreceli olarak başvuruluyorsa, geçerli klasör açıkça belirtilmelidir. Yani, co.ts aynı klasörde (veya derlenmiş çıktı, co.js) ise ./cobunun yerine co.
John Weisz

1
dikkatli olun, "* as xxx" önemlidir. Yani, "
xxx'den

27

Alabildiğim en iyi açıklama Tamas Piro'nun gönderisinden .

TLDR; TypeScript, genel yürütme ortamı için DOM tiplerini kullanır. Sizin durumunuzda, global pencere nesnesinde bir 'co' özelliği vardır.

Bunu çözmek için:

  1. Değişkeni yeniden adlandırın veya
  2. TypeScript modüllerini kullanın ve boş bir dışa aktarma ekleyin {}:
export {};

veya

  1. DOM tiplerini eklemeyerek derleyici seçeneklerinizi yapılandırın:

TypeScript proje dizininde tsconfig.json dosyasını düzenleyin.

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

bu müşteri tarafı için mi? asıl sorunum sunucu tarafı koduyla
ilgiliydi

1
Ben ekleyerek onaylamak export {}Ancak ekleyerek bana sorunu çözmek mi "compilerOptions": { "lib": ["es6"] }ne derleme sırasında ne VSCode yardım görünüyor DEĞİLDİR.
adamsfamily

Orijinal gönderiye bağlantı kesildi.
Cyclonecode

13

Node.JS Typescript uygulamamı derlerken bu benzer hatayı alıyordum:

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

Düzeltme, bunu kaldırmaktı :

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

ve bununla değiştirmek için:

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

9

Kullanım IIFE(Immediately Invoked Function Expression), IIFE

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

 })();

Basit. Mükemmel çalışıyor. Teşekkür ederim! (Benim durumumda const expect = chai.expect;Hıyar testlerini Angular 5 projesinde kullanmak için beyan ediyordum ).
Maxime Lafarie

7

Bu çağda buraya gelenler için işte bu soruna basit bir çözüm. En azından arka uçta benim için çalıştı. Ön uç kodunu kontrol etmedim.

Sadece ekle:

export {};

kodunuzun en üstünde.

EUGENE MURAVITSKY'ye Kredi


1

Bende de aynı sorun var ve çözümüm şuna benziyor:

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

Şimdi bunu sunucu tarafında kullanabiliriz:

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

Ve müşteri tarafında da:

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

Ve tabii ki tüm bunlar için bir yudum dosyası:

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

Güncellenmiş. Elbette, daktilo dosyalarını ayrı ayrı derlemek gerekli değildir. runSequence(['ts1', 'ts2', 'ts3'], 'browserify', callback)mükemmel çalışıyor.


7
Herhangi birinin TypeScript'i o yutkunma dosyasının ayrıntı ve tekrarlılığı nedeniyle ertelemesi durumunda, kimse bunu yapmaz.
Daniel Earwicker 01

0

Bu hatayı yükseltirken aldım

gulp-typcript 3.0.2 → 3.1.0

3.0.2'ye geri koymak sorunu çözdü


0

Benim durumumda aşağıdaki tsconfig.jsonçözülmüş problem:

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

No type: modulein olmamalıdır package.json.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.