typescript - 'Kan inte deklarera om block-skopad variabel' i orelaterade filer
Det finns ett enkelt TS-paket som används som CommonJS-moduler och inte har några exports. TS-filer kompileras till JS-filer med samma namn och används som require('package/option-foo').
tsconfig.json:
{
"compilerOptions": {
"target": "es5"
}
}
option-foo.ts:
declare const GlobalVar: any;
function baz() {}
if (GlobalVar.foo) GlobalVar.baz = baz;
option-bar.ts:
declare const GlobalVar: any;
function baz() {}
if (GlobalVar.bar) GlobalVar.baz = baz;
Den viktiga delen här är att option-foo och option-bar aldrig används tillsammans. Det finns andra kompletterande TS-filer i projektet, men de påverkar ingenting, de behövde bara transpileras till JS i en tsc-körning.
När tsc körs, kastar det
Kan inte deklarera block-scope-variabeln 'GlobalVar' igen.
Duplicera funktionsimplementering.
Kan inte deklarera om blockavgränsad variabel 'GlobalVar'.
Duplicera funktionsimplementering.
för GlobalVar och baz i båda filerna.
Hur kan detta behandlas utan att komplicera byggprocessen eller utdata från dessa två TS-filer?
Svar #1
TL;DR Skriv bara export {} i den yttersta omfattningen av dina filer.
Vid någon tidpunkt behöver det finnas en semantisk avgränsning för om en fil ska behandlas som ett modul (och ha sitt eget omfång) eller som ett skript (och dela det globala omfånget med andra skript).
I webbläsaren är detta enkelt - du bör kunna använda en <script type="module">-tagg och du kommer att kunna använda moduler.
Men vad sägs om någon annan plats som använder JavaScript? Tyvärr finns det för närvarande inget standardiserat sätt att göra den åtskillnaden.
Sättet som TypeScript bestämde sig för att ta itu med problemet var helt enkelt att säga att en modul är vilken fil som helst som innehåller en import eller export.
Så om din fil inte har några slags top-nivå import- eller export-satser, kommer du ibland att se problem med att globala deklarationer stör varandra.
För att komma runt detta kan du enkelt ha ett export-uttryck som inte exporterar något. Med andra ord, skriv bara
export {};
någonstans på toppnivån i din fil.
Svar #2
Från och med TypeScript 4.7 löses detta via "moduleDetection": "force" i din tsconfig.json:
{
"compilerOptions": {
// ... Various options here, such as module ...
"moduleDetection": "force"
}
}
Referens: https://www.typescriptlang.org/tsconfig#moduleDetection
Ursprungligt Github-ärende som drev denna konfiguration: https://github.com/microsoft/TypeScript/issues/14279
Svar #3
GlobalVar och funktionerna exponeras för det globala namnområdet, och TypeScript varnar dig för att variabeln och metoden är omdeklarerade. Eftersom de två funktionerna är deklarerade i det globala namnområdet, behöver du bara deklarera dem en gång.
Om du vill göra detta, använd namnutrymmen.
namespace foo {
declare const GlobalVar: any;
function baz() {}
}
namespace bar {
declare const GlobalVar: any;
function baz() {}
}
Du kan anropa funktionerna på samma sätt som du anropar dem i C#, genom att använda namnrymden: bar.baz eller foo.baz.
