블록 범위 변수 (타입 스크립트)를 재 선언 할 수 없습니다.


106

저는 노드 앱을 구축 중이며 .js의 각 파일 내부에서 다양한 패키지에 필요한 작업을 수행했습니다.

let co = require("co");

하지만 점점

여기에 이미지 설명 입력

등. 그래서 typescript를 사용하면 전체 프로젝트에서 그러한 선언 / 요구 사항이 하나만있을 수있는 것 같습니다. let현재 파일로 범위가 지정 되었다고 생각했기 때문에 이것에 대해 혼란 스럽습니다 .

방금 작동하는 프로젝트가 있었지만 리팩터링 후 이제 모든 곳에서 이러한 오류가 발생합니다.

누군가 설명 할 수 있습니까?


1
이건 어때-let co_module = require ( "co"); 나는 비슷한 일에 직면했고 이것은 오류를 해결했습니다.
tyrion

1
이것은 타이프 스크립트 버그 인 것 같습니다. 여기에 최소한의 예제를 만들었습니다 : gist.github.com/rjmunro/428ec644b6e53a499ca3a5ba8de2edc7
rjmunro

5
2.5 년 후 나는 내 질문으로 돌아 왔지만 이것은 여전히 ​​문제입니다. 이번에는 노드가 내장되어 있습니다. const fs = require('fs')비슷한 오류를 제공하므로 어떤 라이브러리에서 가져올 지 확실하지 않습니다 ...
dcsan aug

TS가 여전히 이것을하고 있다는 사실은 말도 안됩니다
GN.

답변:


68

오류 자체와 관련하여 함수 범위 대신 블록 범위에 존재하는 지역 변수 let를 선언하는 데 사용됩니다 . 또한보다 엄격 하므로 다음과 같은 작업을 수행 할 수 없습니다.var

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

또한 블록 case내부의 절 switch은 자체 블록 범위를 생성하지 않으므로 각 블록을 생성하는 데 case사용하지 않고 여러에서 동일한 지역 변수를 다시 선언 할 수 없습니다 {}.


가져 오기와 관련하여 TypeScript가 파일을 실제 모듈로 인식하지 못하고 겉보기에는 모델 수준 정의가 전역 정의가되기 때문에이 오류가 발생할 수 있습니다.

명시적인 할당을 포함하지 않는 표준 ES6 방식으로 외부 모듈을 가져 오십시오. 그러면 TypeScript가 파일을 모듈로 올바르게 인식해야합니다.

import * as co from "./co"

co예상대로 이미 이름이 지정된 경우 여전히 컴파일 오류가 발생합니다 . 예를 들어, 이것은 오류가 될 것입니다.

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

"cannot find module co" 오류가 발생하는 경우 ...

TypeScript는 모듈에 대해 전체 유형 검사를 실행하므로 가져 오려는 모듈에 대한 TS 정의가없는 경우 (예 : 정의 파일이없는 JS 모듈이기 때문에) 정의 파일 에서 모듈을 선언 할 수 있습니다 .d.ts. 모듈 수준 내보내기를 포함하지 않습니다.

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

9
이것은 "co 모듈을 찾을 수 없음"을 제공합니다. 나는 또한 typings install co주는 시도했다 Unable to find "co" in the registry. 다른 아이디어가 있습니까?
dcsan

@dcsan과 동일한 문제가 있는데 npm이 설치되어 있어도 모듈을 찾을 수 없다고 말합니다.
justin.m.chase

상대 경로로 인해 발생할 수 있습니다. NodeJS 모듈 관리에 익숙하지 않지만 RequireJS에서 모듈이 상대적으로 참조되는 경우 현재 폴더를 명시 적으로 표시해야합니다. 즉, co.ts가 동일한 폴더 (또는 컴파일 된 출력, co.js)에있는 경우 ./co대신 co.
John Weisz

1
"* as xxx"가 중요합니다. 그래서, '가져 오기 xxx는 ...에서 "만"수입 * XXX로에서 ... "
Nurbol Alpysbayev

29

내가 얻을 수있는 가장 좋은 설명은 Tamas Piro의 포스트에서 입니다.

TLDR; TypeScript는 전역 실행 환경을 위해 DOM 유형을 사용합니다. 귀하의 경우에는 전역 창 개체에 'co'속성이 있습니다.

이를 해결하려면 :

  1. 변수 이름을 바꾸거나
  2. TypeScript 모듈을 사용하고 빈 내보내기 {}를 추가합니다.
export {};

또는

  1. DOM 유형을 추가하지 않고 컴파일러 옵션을 구성하십시오.

TypeScript 프로젝트 디렉터리에서 tsconfig.json을 편집합니다.

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

이것은 클라이언트 측입니까? 내 원래 문제는 서버 측 코드에 있었고 DOM 컴파일러 옵션이 사용되었다고 생각하지 않습니다 (이전 프로젝트)
dcsan

2
추가로 export {}문제가 해결 되었음을 확인 했지만 추가 "compilerOptions": { "lib": ["es6"] }는 VSCode에서도 컴파일 중에 도움이되지 않는 것 같습니다.
adamsfamily

1
원래 게시물에 대한 링크가 끊어졌습니다.
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"]
}

10

IIFE(Immediately Invoked Function Expression), IIFE 사용

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

 })();

단순한. 완벽하게 작동합니다. 감사합니다! (제 경우 const expect = chai.expect;에는 Angular 5 프로젝트에서 Cucumber 테스트를 사용하기 위해 선언 했습니다).
Maxime Lafarie

7

이 시대에 오는 사람들을 위해 여기에이 문제에 대한 간단한 해결책이 있습니다. 적어도 백엔드에서 나를 위해 일했습니다. 프런트 엔드 코드로 확인하지 않았습니다.

다음을 추가하십시오.

export {};

코드 상단에 있습니다.

EUGENE MURAVITSKY에 대한 크레딧


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

그리고 물론이 모든 것에 대한 꿀꺽 꿀꺽 파일 :

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

업데이트되었습니다. 물론 타입 스크립트 파일을 따로 컴파일 할 필요는 없습니다. runSequence(['ts1', 'ts2', 'ts3'], 'browserify', callback)완벽하게 작동합니다.


7
누군가가 그 gulp 파일의 장황함과 반복성으로 인해 TypeScript를 미루는 경우를 대비해 아무도 이렇게하지 않습니다.
Daniel Earwicker

0

업그레이드 할 때이 오류가 발생했습니다.

gulp-typescript 3.0.2 → 3.1.0

3.0.2로 되 돌리면 수정되었습니다.


0

제 경우에는 다음과 같은 tsconfig.json문제가 해결되었습니다.

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

어떤이 없어야합니다 type: module에서 package.json.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.