ブロックスコープ変数(typescript)を再宣言できません


99

私はノードアプリを構築しており、.jsの各ファイル内で、さまざまなパッケージでこれを行う必要がありました。

let co = require("co");

しかし、

ここに画像の説明を入力してください

など。タイプスクリプトを使用すると、プロジェクト全体でそのような宣言/要件は1つしか存在できないように思われますか?let現在のファイルにスコープされていると思ったので、これについて混乱しています。

私はちょうど機能していたプロジェクトを持っていましたが、リファクタリングの後、今では至る所でこれらのエラーが発生しています。

誰かが説明できますか?


1
これはどうですか-co_module = require( "co"); 私は似たようなことに直面し、これでエラーが解決しました。
ティリオン2016

1
これはtypescriptのバグのようです。ここで最小限の例を作成しました:gist.github.com/rjmunro/428ec644b6e53a499ca3a5ba8de2edc7
rjmunro

5
2。5年後、私は自分自身の質問に戻りましたが、これはまだ問題です。今回はノードが組み込まれています。const fs = require('fs')同様のエラーが発生するため、これをインポートするライブラリがわからない...
dcsan 2018

TSはまだこれを行うことはばかげている
GN。

回答:


67

エラー自体に関しては、関数スコープではなくブロックスコープに存在letするローカル変数を宣言するために使用されます。また、よりも厳密なので、次のようなことはできません。var

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

また、ブロックcase内の句switchは独自のブロックスコープを作成しないため、それぞれにブロックを作成することなく、複数caseのsにまたがって同じローカル変数を再宣言することはできません{}


インポートに関しては、TypeScriptがファイルを実際のモジュールとして認識せず、モデルレベルの定義がそのグローバル定義になってしまうため、おそらくこのエラーが発生します。

明示的な割り当てを含まない標準のES6の方法で外部モジュールをインポートしてみてください。これにより、TypeScriptでファイルがモジュールとして正しく認識されるようになります。

import * as co from "./co"

co予想どおり、すでに名前が付けられているものがある場合は、これでもコンパイルエラーが発生します。たとえば、これはエラーになります。

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

「モジュールcoが見つかりません」というエラーが発生した場合...

活字体は、(それが定義ファイルなしのJSモジュールですので、例えば)あなたがインポートしようとしているモジュールのTSの定義を持っていない場合ので、あなたがすることができ、完全な型チェックモジュールに対して実行されている宣言で、あなたのモジュールを.d.tsdoesnのことを定義ファイルモジュールレベルのエクスポートは含まれていません:

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

9
これにより、「モジュールcoが見つかりません」というメッセージが表示されます。私も試してみましtypings install coUnable to find "co" in the registry。他のアイデアはありますか?
dcsan 2016

@dcsanと同じ問題が発生していて、明らかにnpmがインストールされていても、モジュールが見つからないと表示されます。
justin.m.chase 2016年

相対パスが原因である可能性があります。私はNodeJSモジュール管理に精通していませんが、RequireJSでモジュールが比較的参照されている場合は、現在のフォルダーを明示的に指定する必要があります。つまり、の./co代わりにco、co.tsが同じフォルダー(またはコンパイルされた出力、co.js)にある場合です。
ジョンワイズ2016年

1
注意してください、「* asxxx」は重要です。したがって、「import xxx from ...」ではなく、「import * as xxx from ...」
Nurbol Alpysbayev 2018年

27

私が得ることができる最も良い説明は、TamasPiroの投稿からです。

TLDR; TypeScriptは、グローバル実行環境にDOM型を使用します。あなたの場合、グローバルウィンドウオブジェクトに「co」プロパティがあります。

これを解決するには:

  1. 変数の名前を変更するか、
  2. TypeScriptモジュールを使用し、空のエクスポートを追加します{}:
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 2018

7

この時代にここに来る人のために、ここにこの問題の簡単な解決策があります。少なくともバックエンドではうまくいきました。フロントエンドコードを確認していません。

追加するだけです:

export {};

コードの上部にあります。

EUGENEMURAVITSKYのクレジット


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-file:

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

更新しました。 もちろん、typescriptファイルを個別にコンパイルする必要はありません。 runSequence(['ts1', 'ts2', 'ts3'], 'browserify', callback)完璧に動作します。


7
そのgulpファイルの冗長性と反復性によって誰かがTypeScriptを延期した場合に備えて、誰もこれを行いません。
Daniel Earwicker 2017年

0

アップグレード時にこのエラーが発生しました

gulp-typescript3.0.2→3.1.0

3.0.2に戻すと修正されました


0

私の場合、次のtsconfig.json問題が解決しました。

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

何があってはなりませんtypemodulepackage.json

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.