Skip to content

Commit b949245

Browse files
authored
Add ValueModule as a valid object literal type, as they are immutable (#19090)
* Add ValueModule as a valid object literal type, as they are immutable * Rename method based on usage
1 parent 9f4130b commit b949245

File tree

5 files changed

+94
-5
lines changed

5 files changed

+94
-5
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6274,7 +6274,7 @@ namespace ts {
62746274
}
62756275

62766276
function getImplicitIndexTypeOfType(type: Type, kind: IndexKind): Type {
6277-
if (isObjectLiteralType(type)) {
6277+
if (isObjectTypeWithInferableIndex(type)) {
62786278
const propTypes: Type[] = [];
62796279
for (const prop of getPropertiesOfType(type)) {
62806280
if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) {
@@ -9831,7 +9831,7 @@ namespace ts {
98319831
// if T is related to U.
98329832
return kind === IndexKind.String && isRelatedTo(getTemplateTypeFromMappedType(<MappedType>source), targetInfo.type, reportErrors);
98339833
}
9834-
if (isObjectLiteralType(source)) {
9834+
if (isObjectTypeWithInferableIndex(source)) {
98359835
let related = Ternary.True;
98369836
if (kind === IndexKind.String) {
98379837
const sourceNumberInfo = getIndexInfoOfType(source, IndexKind.Number);
@@ -10344,11 +10344,11 @@ namespace ts {
1034410344
}
1034510345

1034610346
/**
10347-
* Return true if type was inferred from an object literal or written as an object type literal
10347+
* Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
1034810348
* with no call or construct signatures.
1034910349
*/
10350-
function isObjectLiteralType(type: Type) {
10351-
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral)) !== 0 &&
10350+
function isObjectTypeWithInferableIndex(type: Type) {
10351+
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.ValueModule)) !== 0 &&
1035210352
getSignaturesOfType(type, SignatureKind.Call).length === 0 &&
1035310353
getSignaturesOfType(type, SignatureKind.Construct).length === 0;
1035410354
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [tests/cases/compiler/inferredIndexerOnNamespaceImport.ts] ////
2+
3+
//// [foo.ts]
4+
export const x = 3;
5+
export const y = 5;
6+
7+
//// [bar.ts]
8+
import * as foo from "./foo";
9+
10+
function f(map: { [k: string]: number }) {
11+
// ...
12+
}
13+
14+
f(foo);
15+
16+
//// [foo.js]
17+
"use strict";
18+
exports.__esModule = true;
19+
exports.x = 3;
20+
exports.y = 5;
21+
//// [bar.js]
22+
"use strict";
23+
exports.__esModule = true;
24+
var foo = require("./foo");
25+
function f(map) {
26+
// ...
27+
}
28+
f(foo);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/foo.ts ===
2+
export const x = 3;
3+
>x : Symbol(x, Decl(foo.ts, 0, 12))
4+
5+
export const y = 5;
6+
>y : Symbol(y, Decl(foo.ts, 1, 12))
7+
8+
=== tests/cases/compiler/bar.ts ===
9+
import * as foo from "./foo";
10+
>foo : Symbol(foo, Decl(bar.ts, 0, 6))
11+
12+
function f(map: { [k: string]: number }) {
13+
>f : Symbol(f, Decl(bar.ts, 0, 29))
14+
>map : Symbol(map, Decl(bar.ts, 2, 11))
15+
>k : Symbol(k, Decl(bar.ts, 2, 19))
16+
17+
// ...
18+
}
19+
20+
f(foo);
21+
>f : Symbol(f, Decl(bar.ts, 0, 29))
22+
>foo : Symbol(foo, Decl(bar.ts, 0, 6))
23+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/foo.ts ===
2+
export const x = 3;
3+
>x : 3
4+
>3 : 3
5+
6+
export const y = 5;
7+
>y : 5
8+
>5 : 5
9+
10+
=== tests/cases/compiler/bar.ts ===
11+
import * as foo from "./foo";
12+
>foo : typeof foo
13+
14+
function f(map: { [k: string]: number }) {
15+
>f : (map: { [k: string]: number; }) => void
16+
>map : { [k: string]: number; }
17+
>k : string
18+
19+
// ...
20+
}
21+
22+
f(foo);
23+
>f(foo) : void
24+
>f : (map: { [k: string]: number; }) => void
25+
>foo : typeof foo
26+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @filename: foo.ts
2+
export const x = 3;
3+
export const y = 5;
4+
5+
// @filename: bar.ts
6+
import * as foo from "./foo";
7+
8+
function f(map: { [k: string]: number }) {
9+
// ...
10+
}
11+
12+
f(foo);

0 commit comments

Comments
 (0)