Merge pull request #14222 from Microsoft/addAnyStringIndexerToJSObjects
Add a string indexer to any for object literals on a .js file
This commit is contained in:
commit
b3161e365a
|
@ -244,6 +244,7 @@ namespace ts {
|
|||
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
|
||||
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
|
||||
const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
|
||||
|
||||
const globals = createMap<Symbol>();
|
||||
/**
|
||||
|
@ -12252,6 +12253,7 @@ namespace ts {
|
|||
const contextualType = getApparentTypeOfContextualType(node);
|
||||
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
|
||||
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
|
||||
const isJSObjectLiteral = !contextualType && isInJavaScriptFile(node);
|
||||
let typeFlags: TypeFlags = 0;
|
||||
let patternWithComputedProperties = false;
|
||||
let hasComputedStringProperty = false;
|
||||
|
@ -12389,8 +12391,8 @@ namespace ts {
|
|||
return createObjectLiteralType();
|
||||
|
||||
function createObjectLiteralType() {
|
||||
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.String) : undefined;
|
||||
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.Number) : undefined;
|
||||
const stringIndexInfo = isJSObjectLiteral ? jsObjectLiteralIndexInfo : hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.String) : undefined;
|
||||
const numberIndexInfo = hasComputedNumberProperty && !isJSObjectLiteral ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.Number) : undefined;
|
||||
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
|
||||
result.flags |= TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
=== tests/cases/compiler/a.js ===
|
||||
|
||||
function foo() {
|
||||
>foo : () => { a: number; b: string; }
|
||||
>foo : () => { [x: string]: any; a: number; b: string; }
|
||||
|
||||
var a = 10;
|
||||
>a : number
|
||||
|
@ -12,7 +12,7 @@ function foo() {
|
|||
>"Hello" : "Hello"
|
||||
|
||||
return {
|
||||
>{ a, b } : { a: number; b: string; }
|
||||
>{ a, b } : { [x: string]: any; a: number; b: string; }
|
||||
|
||||
a,
|
||||
>a : number
|
||||
|
|
63
tests/baselines/reference/jsObjectsMarkedAsOpenEnded.js
Normal file
63
tests/baselines/reference/jsObjectsMarkedAsOpenEnded.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
//// [tests/cases/conformance/salsa/jsObjectsMarkedAsOpenEnded.ts] ////
|
||||
|
||||
//// [a.js]
|
||||
|
||||
var variable = {};
|
||||
variable.a = 0;
|
||||
|
||||
class C {
|
||||
initializedMember = {};
|
||||
constructor() {
|
||||
this.member = {};
|
||||
this.member.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
property: {}
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
|
||||
var arr = [{}];
|
||||
|
||||
function getObj() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
//// [b.ts]
|
||||
variable.a = 1;
|
||||
(new C()).member.a = 1;
|
||||
(new C()).initializedMember.a = 1;
|
||||
obj.property.a = 1;
|
||||
arr[0].a = 1;
|
||||
getObj().a = 1;
|
||||
|
||||
|
||||
|
||||
//// [output.js]
|
||||
var variable = {};
|
||||
variable.a = 0;
|
||||
var C = (function () {
|
||||
function C() {
|
||||
this.initializedMember = {};
|
||||
this.member = {};
|
||||
this.member.a = 0;
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var obj = {
|
||||
property: {}
|
||||
};
|
||||
obj.property.a = 0;
|
||||
var arr = [{}];
|
||||
function getObj() {
|
||||
return {};
|
||||
}
|
||||
variable.a = 1;
|
||||
(new C()).member.a = 1;
|
||||
(new C()).initializedMember.a = 1;
|
||||
obj.property.a = 1;
|
||||
arr[0].a = 1;
|
||||
getObj().a = 1;
|
76
tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols
Normal file
76
tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols
Normal file
|
@ -0,0 +1,76 @@
|
|||
=== tests/cases/conformance/salsa/a.js ===
|
||||
|
||||
var variable = {};
|
||||
>variable : Symbol(variable, Decl(a.js, 1, 3))
|
||||
|
||||
variable.a = 0;
|
||||
>variable : Symbol(variable, Decl(a.js, 1, 3))
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(a.js, 2, 15))
|
||||
|
||||
initializedMember = {};
|
||||
>initializedMember : Symbol(C.initializedMember, Decl(a.js, 4, 9))
|
||||
|
||||
constructor() {
|
||||
this.member = {};
|
||||
>this.member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
>this : Symbol(C, Decl(a.js, 2, 15))
|
||||
>member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
|
||||
this.member.a = 0;
|
||||
>this.member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
>this : Symbol(C, Decl(a.js, 2, 15))
|
||||
>member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
>obj : Symbol(obj, Decl(a.js, 12, 3))
|
||||
|
||||
property: {}
|
||||
>property : Symbol(property, Decl(a.js, 12, 11))
|
||||
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
>obj.property : Symbol(property, Decl(a.js, 12, 11))
|
||||
>obj : Symbol(obj, Decl(a.js, 12, 3))
|
||||
>property : Symbol(property, Decl(a.js, 12, 11))
|
||||
|
||||
var arr = [{}];
|
||||
>arr : Symbol(arr, Decl(a.js, 18, 3))
|
||||
|
||||
function getObj() {
|
||||
>getObj : Symbol(getObj, Decl(a.js, 18, 15))
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
=== tests/cases/conformance/salsa/b.ts ===
|
||||
variable.a = 1;
|
||||
>variable : Symbol(variable, Decl(a.js, 1, 3))
|
||||
|
||||
(new C()).member.a = 1;
|
||||
>(new C()).member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
>C : Symbol(C, Decl(a.js, 2, 15))
|
||||
>member : Symbol(C.member, Decl(a.js, 6, 19))
|
||||
|
||||
(new C()).initializedMember.a = 1;
|
||||
>(new C()).initializedMember : Symbol(C.initializedMember, Decl(a.js, 4, 9))
|
||||
>C : Symbol(C, Decl(a.js, 2, 15))
|
||||
>initializedMember : Symbol(C.initializedMember, Decl(a.js, 4, 9))
|
||||
|
||||
obj.property.a = 1;
|
||||
>obj.property : Symbol(property, Decl(a.js, 12, 11))
|
||||
>obj : Symbol(obj, Decl(a.js, 12, 3))
|
||||
>property : Symbol(property, Decl(a.js, 12, 11))
|
||||
|
||||
arr[0].a = 1;
|
||||
>arr : Symbol(arr, Decl(a.js, 18, 3))
|
||||
|
||||
getObj().a = 1;
|
||||
>getObj : Symbol(getObj, Decl(a.js, 18, 15))
|
||||
|
||||
|
128
tests/baselines/reference/jsObjectsMarkedAsOpenEnded.types
Normal file
128
tests/baselines/reference/jsObjectsMarkedAsOpenEnded.types
Normal file
|
@ -0,0 +1,128 @@
|
|||
=== tests/cases/conformance/salsa/a.js ===
|
||||
|
||||
var variable = {};
|
||||
>variable : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
variable.a = 0;
|
||||
>variable.a = 0 : 0
|
||||
>variable.a : any
|
||||
>variable : { [x: string]: any; }
|
||||
>a : any
|
||||
>0 : 0
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
initializedMember = {};
|
||||
>initializedMember : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
constructor() {
|
||||
this.member = {};
|
||||
>this.member = {} : { [x: string]: any; }
|
||||
>this.member : { [x: string]: any; }
|
||||
>this : this
|
||||
>member : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
this.member.a = 0;
|
||||
>this.member.a = 0 : 0
|
||||
>this.member.a : any
|
||||
>this.member : { [x: string]: any; }
|
||||
>this : this
|
||||
>member : { [x: string]: any; }
|
||||
>a : any
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
>obj : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
>{ property: {}} : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
|
||||
property: {}
|
||||
>property : { [x: string]: any; }
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
>obj.property.a = 0 : 0
|
||||
>obj.property.a : any
|
||||
>obj.property : { [x: string]: any; }
|
||||
>obj : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
>property : { [x: string]: any; }
|
||||
>a : any
|
||||
>0 : 0
|
||||
|
||||
var arr = [{}];
|
||||
>arr : { [x: string]: any; }[]
|
||||
>[{}] : { [x: string]: any; }[]
|
||||
>{} : { [x: string]: any; }
|
||||
|
||||
function getObj() {
|
||||
>getObj : () => { [x: string]: any; }
|
||||
|
||||
return {};
|
||||
>{} : { [x: string]: any; }
|
||||
}
|
||||
|
||||
|
||||
=== tests/cases/conformance/salsa/b.ts ===
|
||||
variable.a = 1;
|
||||
>variable.a = 1 : 1
|
||||
>variable.a : any
|
||||
>variable : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
(new C()).member.a = 1;
|
||||
>(new C()).member.a = 1 : 1
|
||||
>(new C()).member.a : any
|
||||
>(new C()).member : { [x: string]: any; }
|
||||
>(new C()) : C
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
>member : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
(new C()).initializedMember.a = 1;
|
||||
>(new C()).initializedMember.a = 1 : 1
|
||||
>(new C()).initializedMember.a : any
|
||||
>(new C()).initializedMember : { [x: string]: any; }
|
||||
>(new C()) : C
|
||||
>new C() : C
|
||||
>C : typeof C
|
||||
>initializedMember : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
obj.property.a = 1;
|
||||
>obj.property.a = 1 : 1
|
||||
>obj.property.a : any
|
||||
>obj.property : { [x: string]: any; }
|
||||
>obj : { [x: string]: any; property: { [x: string]: any; }; }
|
||||
>property : { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
arr[0].a = 1;
|
||||
>arr[0].a = 1 : 1
|
||||
>arr[0].a : any
|
||||
>arr[0] : { [x: string]: any; }
|
||||
>arr : { [x: string]: any; }[]
|
||||
>0 : 0
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
getObj().a = 1;
|
||||
>getObj().a = 1 : 1
|
||||
>getObj().a : any
|
||||
>getObj() : { [x: string]: any; }
|
||||
>getObj : () => { [x: string]: any; }
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
=== /a.ts ===
|
||||
import foo from "foo";
|
||||
>foo : { bar(): number; }
|
||||
>foo : { [x: string]: any; bar(): number; }
|
||||
|
||||
foo.bar();
|
||||
>foo.bar() : number
|
||||
>foo.bar : () => number
|
||||
>foo : { bar(): number; }
|
||||
>foo : { [x: string]: any; bar(): number; }
|
||||
>bar : () => number
|
||||
|
||||
=== /node_modules/foo/index.js ===
|
||||
// Same as untypedModuleImport.ts but with --allowJs, so the package will actually be typed.
|
||||
|
||||
exports.default = { bar() { return 0; } }
|
||||
>exports.default = { bar() { return 0; } } : { bar(): number; }
|
||||
>exports.default = { bar() { return 0; } } : { [x: string]: any; bar(): number; }
|
||||
>exports.default : any
|
||||
>exports : any
|
||||
>default : any
|
||||
>{ bar() { return 0; } } : { bar(): number; }
|
||||
>{ bar() { return 0; } } : { [x: string]: any; bar(): number; }
|
||||
>bar : () => number
|
||||
>0 : 0
|
||||
|
||||
|
|
36
tests/cases/conformance/salsa/jsObjectsMarkedAsOpenEnded.ts
Normal file
36
tests/cases/conformance/salsa/jsObjectsMarkedAsOpenEnded.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
// @out: output.js
|
||||
// @allowJs: true
|
||||
|
||||
// @filename: a.js
|
||||
var variable = {};
|
||||
variable.a = 0;
|
||||
|
||||
class C {
|
||||
initializedMember = {};
|
||||
constructor() {
|
||||
this.member = {};
|
||||
this.member.a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = {
|
||||
property: {}
|
||||
};
|
||||
|
||||
obj.property.a = 0;
|
||||
|
||||
var arr = [{}];
|
||||
|
||||
function getObj() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
// @filename: b.ts
|
||||
variable.a = 1;
|
||||
(new C()).member.a = 1;
|
||||
(new C()).initializedMember.a = 1;
|
||||
obj.property.a = 1;
|
||||
arr[0].a = 1;
|
||||
getObj().a = 1;
|
||||
|
Loading…
Reference in a new issue