Avatar ·

Ошибка TypeScript: "Cannot write file ... because it would overwrite input file" в Visual Studio

Всем привет! Я новичок в TypeScript, пишу на нём в Visual Studio 2015. Установил TypeScript 2.0 через NuGet. Создал простой проект, где есть один файл app.ts:

function greet(name: string) {
    return `Hello, ${name}!`;
}

console.log(greet('World'));

В tsconfig.json у меня прописано:

{
    "compilerOptions": {
        "target": "es5",
        "outDir": "./dist",
        "rootDir": "./src"
    },
    "include": [
        "src/**/*"
    ]
}

Файл app.ts лежит в папке src. При попытке собрать проект (Ctrl+Shift+B) я получаю ошибку:

Cannot write file 'C:/Projects/MyApp/dist/app.js' because it would overwrite input file.

Я перепроверил: в папке dist нет никаких .ts файлов. Почему компилятор думает, что он перезаписывает входной файл? Как это исправить? Пробовал удалять папки dist и node_modules, чистить кэш — не помогает. Версия TypeScript 2.0.3, Visual Studio 2015 Update 3.

<<>>

Причина ошибки: компилятор видит файл .js как исходный

Ошибка "Cannot write file ... because it would overwrite input file" возникает, когда TypeScript пытается записать скомпилированный JavaScript-файл в то же место, где находится исходный TypeScript-файл (или файл, который компилятор считает исходным). В вашем случае проблема в том, что компилятор "видит" файл dist/app.js как входной, хотя он должен быть только выходным.

Это происходит из-за того, что TypeScript по умолчанию включает в компиляцию все .ts и .js файлы в проекте. Когда вы указываете outDir: "./dist", компилятор создаёт dist/app.js. Но если в dist уже есть .ts файл (или компилятор ошибочно считает .js файл входным из-за настроек), он отказывается его перезаписывать.

Решение 1: Исключить выходную папку из компиляции

Добавьте в tsconfig.json опцию "exclude", чтобы компилятор игнорировал папку dist:

{
    "compilerOptions": {
        "target": "es5",
        "outDir": "./dist",
        "rootDir": "./src"
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "dist",
        "node_modules"
    ]
}

Решение 2: Указать явно, какие файлы включать

Вместо "include" можно использовать "files" — это самый строгий способ:

{
    "compilerOptions": {
        "target": "es5",
        "outDir": "./dist",
        "rootDir": "./src"
    },
    "files": [
        "src/app.ts"
    ]
}

Решение 3: Проверить настройки Visual Studio

В Visual Studio 2015 с TypeScript 2.0 иногда возникает конфликт между настройками tsconfig.json и глобальными настройками проекта. Сделайте следующее:

  • Правый клик на проекте → Properties → вкладка TypeScript Build.
  • Убедитесь, что "Compile on save" выключен, если вы используете tsconfig.json.
  • В поле "Root directory of tsconfig" укажите путь к папке, где лежит tsconfig.json.

Решение 4: Удалить лишние файлы .js

Иногда в папке src могут остаться старые .js файлы (если вы раньше компилировали без outDir). Проверьте:

src/
  app.ts
  app.js  <-- этот файл нужно удалить!

Если app.js лежит рядом с app.ts, компилятор может путаться. Удалите все .js файлы из src.

Решение 5: Использовать allowJs (если нужно)

Если вам нужно, чтобы TypeScript обрабатывал JavaScript-файлы, используйте опцию "allowJs": true, но тогда явно исключите выходную папку:

{
    "compilerOptions": {
        "target": "es5",
        "outDir": "./dist",
        "rootDir": "./src",
        "allowJs": true
    },
    "include": ["src/**/*"],
    "exclude": ["dist", "node_modules"]
}

После любого из этих решений перезапустите сборку (Clean Solution → Rebuild). Ошибка должна исчезнуть.

<<>>

Альтернативный подход: настройка через Visual Studio без tsconfig.json

Если вы не хотите разбираться с tsconfig.json, можно полностью управлять компиляцией через интерфейс Visual Studio. Это особенно актуально для версии 2015, где интеграция TypeScript иногда конфликтует с конфигурационными файлами.

Сделайте следующее:

  • Удалите tsconfig.json из проекта (или переименуйте его, чтобы VS его не видел).
  • Правый клик на проекте → Properties → вкладка TypeScript Build.
  • Установите:
    • ECMAScript version: ES5
    • Output directory: dist (относительно корня проекта)
    • Root directory: src
    • Combine generated output: false

После этого Visual Studio будет компилировать все .ts файлы из папки src в папку dist, игнорируя при этом любые .js файлы. Важно: если у вас в проекте есть другие .ts файлы вне src, они тоже будут скомпилированы — следите за этим.

Этот метод менее гибкий, чем tsconfig.json, но для простых проектов он надёжнее, так как Visual Studio сама управляет путями и не допускает перезаписи.