You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
By default (with esModuleInterop false or not set) TypeScript treats CommonJS/AMD/UMD modules similar to ES6 modules. In doing this, there are two parts in particular which turned out to be flawed assumptions:
295
+
296
+
a namespace import like `import*asmomentfrom"moment"` acts the same as `const moment = require("moment")`
297
+
298
+
a default import like `importmomentfrom"moment"` acts the same as `const moment = require("moment").default`
299
+
300
+
This mis-match causes these two issues:
301
+
302
+
- the ES6 modules spec states that a namespace import (import * as x) can only be an object, by having TypeScript treating it the same as = require("x") then TypeScript allowed for the import to be treated as a function and be callable. That’s not valid according to the spec.
303
+
304
+
- while accurate to the ES6 modules spec, most libraries with CommonJS/AMD/UMD modules didn’t conform as strictly as TypeScript’s implementation.
305
+
306
+
307
+
##### Note
308
+
309
+
The namespace import `import*asfsfrom"fs"` only accounts for properties which are **owned** (basically properties set on the object and not via the prototype chain) on the imported object. If the module you’re importing defines its API using inherited properties, you need to use the default import form (`importfsfrom"fs"`), or *disable esModuleInterop*.
> [Below is copied from this comment, see https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492](https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492)
343
371
344
372
We will not be removing `{}` from the rule defaults, as it is an unsafe type because it doesn't work how people think it works, and in most cases it allows weakly typed code.
345
373
346
-
---
347
374
348
375
This is the exact reason that the rule bans the `{}` ***type***.
349
376
It's a common misconception that the `{}` ***type*** is the same as the `{}` ***value***.
@@ -355,7 +382,7 @@ This is obviously a huge type safety hole!
355
382
356
383
For example - the following code is _completely type-check valid_, even though it might make no sense to be:
357
384
358
-
```ts
385
+
```typescript
359
386
interfaceAAA {
360
387
aaa: {};
361
388
}
@@ -376,7 +403,7 @@ There are the following options for you:
376
403
377
404
You can use a type similar to this type.
378
405
379
-
```ts
406
+
```typescript
380
407
type EmptyObject = Record<string, never>; // or {[k: string]: never}
381
408
382
409
const a:EmptyObject= { a:1 }; // expect error
@@ -414,11 +441,9 @@ You can use the following config to allow it:
414
441
415
442
Consider using [an eslint overrides config](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns) to limit the scope of this change to just react component files, to help ensure you're keeping your codebase as safe as possible.
416
443
417
-
----
418
-
419
444
As an aside - it's worth noting that `{}` is a very weird anomaly in TypeScript, because there is just one case where it actually does mean something akin to "empty object"; in an intersection type.
420
445
421
-
```ts
446
+
```typescript
422
447
type T1= { a:1 } & {};
423
448
const t11:T1= { a:1 };
424
449
const t12:T1=true; // expected error
@@ -480,7 +505,7 @@ A module map is a [map](https://infra.spec.whatwg.org/#ordered-map) keyed by [tu
480
505
481
506
Since [module maps](https://html.spec.whatwg.org/multipage/webappapis.html#module-map) are keyed by (URL, module type), the following code will create three separate entries in the [module map](https://html.spec.whatwg.org/multipage/webappapis.html#module-map), since it results in three different (URL, module type) [tuples](https://infra.spec.whatwg.org/#tuple) (all with "`javascript`" type):
@@ -490,7 +515,7 @@ That is, URL [queries](https://url.spec.whatwg.org/#concept-url-query) and [frag
490
515
491
516
In contrast, the following code would only create a single entry in the [module map](https://html.spec.whatwg.org/multipage/webappapis.html#module-map), since after applying the [URL parser](https://url.spec.whatwg.org/#concept-url-parser) to these inputs, the resulting [URL records](https://url.spec.whatwg.org/#concept-url) are equal:
492
517
493
-
```
518
+
```typescript
494
519
import "https://example.com/module2.mjs";
495
520
import "https:example.com/module2.mjs";
496
521
import "https://///example.com\\module2.mjs";
@@ -503,7 +528,7 @@ Note that this behavior is the same as how [shared workers](https://html.spec.wh
503
528
504
529
Since module type is also part of the [module map](https://html.spec.whatwg.org/multipage/webappapis.html#module-map) key, the following code will create two separate entries in the [module map](https://html.spec.whatwg.org/multipage/webappapis.html#module-map) (the type is "`javascript`" for the first, and "`css`" for the second):
505
530
506
-
```
531
+
```html
507
532
<script type=module>
508
533
import "https://example.com/module";
509
534
</script>
@@ -520,7 +545,7 @@ The purpose of including the type in the [module map](https://html.spec.whatwg.o
520
545
521
546
JavaScript module scripts are the default importtypewhenimportingfrom another JavaScript module; that is, when an `import` statement lacks a `type`import assertion the imported module script's type will be JavaScript. Attempting to import a JavaScript resource using an `import` statement with a `type` import assertion will fail:
522
547
523
-
```
548
+
```html
524
549
<script type="module">
525
550
// All of the following will fail, assuming that the imported .mjs files are served with a
526
551
// JavaScript MIME type. JavaScript module scripts are the default and cannot be imported with
@@ -569,3 +594,8 @@ The following are not valid module specifiers according to the above algorithm:
0 commit comments