9

Contents of foo.ts:

let a: Person = new Person();

Contents of bar.ts:

class Person {}

The tsconfig.json file contains the default set of values created by tsc --init.

I'm using typescript version 2.6.2.

The code above simply compiles with no errors about Person being not defined. If I rename Person to Persons in foo.ts, then it does throw an error saying cannot find name 'Persons'. So it's as if it is automatically importing this file somehow.

Also note that I'm not exporting the Person class in bar.ts. If I do add an export statement, then everything behaves as it should - I get an error saying cannot find name 'Person'.

Does anyone know what's going on here? Is this a user error?

Edit:

Maybe this makes sense in the browser, but to me this behavior makes no sense in a node.js application. Is there a Typescript flag which forbids this behavior?

Shivanshu Goyal
  • 1,374
  • 2
  • 16
  • 22

2 Answers2

3

Your bar.ts is not a module, since it doesn't have any import nor any export. So it defines a global Person class, that doesn't need to be imported, since it's global. Export it, and TypeScript will complain about the missing import.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    But the point is compiling this code is successful, but when you run it, node.js throws an error saying that it can't find the variable Person. Typescript is supposed to catch runtime failures like this at compile time. – Shivanshu Goyal Jan 17 '18 at 17:54
  • 3
    Well, if you choose to use global classes instead of properly using modules, you are shooting yourself in the foot. TypeScript must support global classes, because they exist in JS. That doesn't mean it's a good idea to use them. – JB Nizet Jan 17 '18 at 18:06
  • Similar code would also throw an error in node.js because it doesn't have a concept of global classes. So I'm wondering if there's a compiler option in typescript which forbids global classes. – Shivanshu Goyal Jan 17 '18 at 18:29
  • I though about the `module` compiler option, but the default is `CommonJS` i.e. adapted for NodeJs! Perhaps with the value `ES6` but it will change your modules syntax (e.g. from `required()` to `import ...`) – Romain Deneau Jan 18 '18 at 21:11
  • 1
    @ShivanshuGoyal it looks like a compiler option is being debated: https://github.com/microsoft/TypeScript/issues/14306 – AJP Nov 22 '20 at 12:53
2

The compiler flag --isolatedModules will ensure that all .ts files are modules. Once you make foo.ts and bar.ts modules by adding at 1 import or export, then the Person class will not be global anymore.

This, however doesn't solve the following similar issue: https://github.com/Microsoft/TypeScript/issues/18232#issuecomment-359200157

Shivanshu Goyal
  • 1,374
  • 2
  • 16
  • 22