Flag JS Literals and ignore assignments/accesses to invalid props, instead of adding an index (#25996)

* Remove index signatures from js literals, use an object flag to indicate errors should be ignored instead

* Add focused test on the keyof problem

* Fix fourslash test

* Reenable errors with noImplicitAny flag

* Also disable excess property checks outside of noImplicitAny mode for js literals

* Edit and move comments
This commit is contained in:
Wesley Wigham
2018-08-02 13:40:44 -07:00
committed by GitHub
parent eb763f0792
commit fefc47fae3
65 changed files with 526 additions and 369 deletions

View File

@@ -425,7 +425,6 @@ namespace ts {
const resolvingSignaturesArray = [resolvingSignature];
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
const globals = createSymbolTable();
let amalgamatedDuplicates: Map<{ firstFile: SourceFile, secondFile: SourceFile, firstFileInstances: Map<{ instances: Node[], blockScoped: boolean }>, secondFileInstances: Map<{ instances: Node[], blockScoped: boolean }> }> | undefined;
@@ -4809,13 +4808,15 @@ namespace ts {
members.set(name, s);
}
});
return createAnonymousType(
const result = createAnonymousType(
exportedType.symbol,
members,
exportedType.callSignatures,
exportedType.constructSignatures,
exportedType.stringIndexInfo,
exportedType.numberIndexInfo);
result.objectFlags |= (getObjectFlags(type) & ObjectFlags.JSLiteral); // Propagate JSLiteral flag
return result;
}
if (isEmptyArrayLiteralType(type)) {
if (noImplicitAny) {
@@ -5123,7 +5124,9 @@ namespace ts {
if (s && hasEntries(s.exports)) {
mergeSymbolTable(exports, s.exports);
}
return createAnonymousType(symbol, exports, emptyArray, emptyArray, jsObjectLiteralIndexInfo, undefined);
const type = createAnonymousType(symbol, exports, emptyArray, emptyArray, undefined, undefined);
type.objectFlags |= ObjectFlags.JSLiteral;
return type;
}
}
@@ -9074,6 +9077,34 @@ namespace ts {
return type;
}
/**
* Returns if a type is or consists of a JSLiteral object type
* In addition to objects which are directly literals,
* * unions where every element is a jsliteral
* * intersections where at least one element is a jsliteral
* * and instantiable types constrained to a jsliteral
* Should all count as literals and not print errors on access or assignment of possibly existing properties.
* This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference).
*/
function isJSLiteralType(type: Type): boolean {
if (noImplicitAny) {
return false; // Flag is meaningless under `noImplicitAny` mode
}
if (getObjectFlags(type) & ObjectFlags.JSLiteral) {
return true;
}
if (type.flags & TypeFlags.Union) {
return every((type as UnionType).types, isJSLiteralType);
}
if (type.flags & TypeFlags.Intersection) {
return some((type as IntersectionType).types, isJSLiteralType);
}
if (type.flags & TypeFlags.Instantiable) {
return isJSLiteralType(getResolvedBaseConstraint(type));
}
return false;
}
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | undefined, cacheSymbol: boolean) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
const propName = isTypeUsableAsLateBoundName(indexType) ? getLateBoundNameFromType(indexType) :
@@ -9122,6 +9153,9 @@ namespace ts {
if (indexType.flags & TypeFlags.Never) {
return neverType;
}
if (isJSLiteralType(objectType)) {
return anyType;
}
if (accessExpression && !isConstEnumObjectType(objectType)) {
if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
if (getIndexTypeOfType(objectType, IndexKind.Number)) {
@@ -9142,6 +9176,9 @@ namespace ts {
return anyType;
}
}
if (isJSLiteralType(objectType)) {
return anyType;
}
if (accessNode) {
const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType;
if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
@@ -11217,6 +11254,9 @@ namespace ts {
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, discriminant: Type | undefined, reportErrors: boolean): boolean {
if (!noImplicitAny && getObjectFlags(target) & ObjectFlags.JSLiteral) {
return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny
}
if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
if ((relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) &&
@@ -12705,7 +12745,7 @@ namespace ts {
resolved.stringIndexInfo,
resolved.numberIndexInfo);
regularNew.flags = resolved.flags & ~TypeFlags.FreshLiteral;
regularNew.objectFlags |= ObjectFlags.ObjectLiteral;
regularNew.objectFlags |= ObjectFlags.ObjectLiteral | (getObjectFlags(resolved) & ObjectFlags.JSLiteral);
(<FreshObjectLiteralType>type).regularType = regularNew;
return regularNew;
}
@@ -12784,9 +12824,11 @@ namespace ts {
}
const stringIndexInfo = getIndexInfoOfType(type, IndexKind.String);
const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number);
return createAnonymousType(type.symbol, members, emptyArray, emptyArray,
const result = createAnonymousType(type.symbol, members, emptyArray, emptyArray,
stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly),
numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
result.objectFlags |= (getObjectFlags(type) & ObjectFlags.JSLiteral); // Retain js literal flag through widening
return result;
}
function getWidenedType(type: Type) {
@@ -16791,12 +16833,15 @@ namespace ts {
return createObjectLiteralType();
function createObjectLiteralType() {
const stringIndexInfo = isJSObjectLiteral ? jsObjectLiteralIndexInfo : hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, IndexKind.String) : undefined;
const stringIndexInfo = 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);
result.objectFlags |= ObjectFlags.ObjectLiteral;
if (isJSObjectLiteral) {
result.objectFlags |= ObjectFlags.JSLiteral;
}
if (patternWithComputedProperties) {
result.objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties;
}
@@ -17872,6 +17917,9 @@ namespace ts {
if (!prop) {
const indexInfo = getIndexInfoOfType(apparentType, IndexKind.String);
if (!(indexInfo && indexInfo.type)) {
if (isJSLiteralType(leftType)) {
return anyType;
}
if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
reportNonexistentProperty(right, leftType.flags & TypeFlags.TypeParameter && (leftType as TypeParameter).isThisType ? apparentType : leftType);
}
@@ -20009,7 +20057,8 @@ namespace ts {
if (decl) {
const jsSymbol = getSymbolOfNode(decl);
if (jsSymbol && hasEntries(jsSymbol.exports)) {
jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, jsObjectLiteralIndexInfo, undefined);
jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, undefined, undefined);
(jsAssignmentType as ObjectType).objectFlags |= ObjectFlags.JSLiteral;
}
}
}

View File

@@ -3824,6 +3824,7 @@ namespace ts {
ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type
JsxAttributes = 1 << 12, // Jsx attributes type
MarkerType = 1 << 13, // Marker type used for variance probing
JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members
ClassOrInterface = Class | Interface
}

View File

@@ -2231,6 +2231,7 @@ declare namespace ts {
ReverseMapped = 2048,
JsxAttributes = 4096,
MarkerType = 8192,
JSLiteral = 16384,
ClassOrInterface = 3
}
interface ObjectType extends Type {

View File

@@ -2231,6 +2231,7 @@ declare namespace ts {
ReverseMapped = 2048,
JsxAttributes = 4096,
MarkerType = 8192,
JSLiteral = 16384,
ClassOrInterface = 3
}
interface ObjectType extends Type {

View File

@@ -7,15 +7,15 @@ var mod = require('./mod');
>'./mod' : "./mod"
var a = new mod.A()
>a : A & { [x: string]: any; m(n: number): number; }
>new mod.A() : A & { [x: string]: any; m(n: number): number; }
>a : A & { m(n: number): number; }
>new mod.A() : A & { m(n: number): number; }
>mod.A : typeof A
>mod : typeof import("tests/cases/conformance/salsa/mod")
>A : typeof A
var b = new mod.B()
>b : B & { [x: string]: any; m(n: number): number; }
>new mod.B() : B & { [x: string]: any; m(n: number): number; }
>b : B & { m(n: number): number; }
>new mod.B() : B & { m(n: number): number; }
>mod.B : typeof B
>mod : typeof import("tests/cases/conformance/salsa/mod")
>B : typeof B
@@ -23,14 +23,14 @@ var b = new mod.B()
a.m('nope')
>a.m('nope') : number
>a.m : (n: number) => number
>a : A & { [x: string]: any; m(n: number): number; }
>a : A & { m(n: number): number; }
>m : (n: number) => number
>'nope' : "nope"
b.m('not really')
>b.m('not really') : number
>b.m : (n: number) => number
>b : B & { [x: string]: any; m(n: number): number; }
>b : B & { m(n: number): number; }
>m : (n: number) => number
>'not really' : "not really"
@@ -81,15 +81,15 @@ exports.B = B
>B : typeof B
A.prototype = B.prototype = {
>A.prototype = B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; }
>A.prototype : { [x: string]: any; m(n: number): number; }
>A.prototype = B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { m(n: number): number; }
>A.prototype : { m(n: number): number; }
>A : typeof A
>prototype : { [x: string]: any; m(n: number): number; }
>B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; }
>B.prototype : { [x: string]: any; m(n: number): number; }
>prototype : { m(n: number): number; }
>B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { m(n: number): number; }
>B.prototype : { m(n: number): number; }
>B : typeof B
>prototype : { [x: string]: any; m(n: number): number; }
>{ /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; }
>prototype : { m(n: number): number; }
>{ /** @param {number} n */ m(n) { return n + 1 }} : { m(n: number): number; }
/** @param {number} n */
m(n) {

View File

@@ -1,17 +1,17 @@
=== tests/cases/compiler/bug25434.js ===
// should not crash while checking
function Test({ b = '' } = {}) {}
>Test : ({ b }?: { [x: string]: any; }) => void
>Test : ({ b }?: {}) => void
>b : string
>'' : ""
>{} : { b?: string; }
Test(({ b = '5' } = {}));
>Test(({ b = '5' } = {})) : void
>Test : ({ b }?: { [x: string]: any; }) => void
>Test : ({ b }?: {}) => void
>({ b = '5' } = {}) : { b?: any; }
>{ b = '5' } = {} : { b?: any; }
>{ b = '5' } : { [x: string]: any; b?: any; }
>{ b = '5' } : { b?: any; }
>b : any
>'5' : "5"
>{} : { b?: any; }

View File

@@ -0,0 +1,18 @@
tests/cases/compiler/file.js(11,1): error TS2322: Type '"z"' is not assignable to type '"x" | "y"'.
==== tests/cases/compiler/file.js (1 errors) ====
// @ts-check
const obj = {
x: 1,
y: 2
};
/**
* @type {keyof typeof obj}
*/
let selected = "x";
selected = "z"; // should fail
~~~~~~~~
!!! error TS2322: Type '"z"' is not assignable to type '"x" | "y"'.

View File

@@ -0,0 +1,25 @@
//// [file.js]
// @ts-check
const obj = {
x: 1,
y: 2
};
/**
* @type {keyof typeof obj}
*/
let selected = "x";
selected = "z"; // should fail
//// [file.js]
// @ts-check
var obj = {
x: 1,
y: 2
};
/**
* @type {keyof typeof obj}
*/
var selected = "x";
selected = "z"; // should fail

View File

@@ -0,0 +1,22 @@
=== tests/cases/compiler/file.js ===
// @ts-check
const obj = {
>obj : Symbol(obj, Decl(file.js, 1, 5))
x: 1,
>x : Symbol(x, Decl(file.js, 1, 13))
y: 2
>y : Symbol(y, Decl(file.js, 2, 9))
};
/**
* @type {keyof typeof obj}
*/
let selected = "x";
>selected : Symbol(selected, Decl(file.js, 9, 3))
selected = "z"; // should fail
>selected : Symbol(selected, Decl(file.js, 9, 3))

View File

@@ -0,0 +1,28 @@
=== tests/cases/compiler/file.js ===
// @ts-check
const obj = {
>obj : { x: number; y: number; }
>{ x: 1, y: 2} : { x: number; y: number; }
x: 1,
>x : number
>1 : 1
y: 2
>y : number
>2 : 2
};
/**
* @type {keyof typeof obj}
*/
let selected = "x";
>selected : "x" | "y"
>"x" : "x"
selected = "z"; // should fail
>selected = "z" : "z"
>selected : "x" | "y"
>"z" : "z"

View File

@@ -5,8 +5,8 @@ var lol = "hello Lol"
>"hello Lol" : "hello Lol"
const obj = {
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>{ /** @type {string|undefined} */ foo: undefined, /** @type {string|undefined} */ bar: "42", /** @type {function(number): number} */ method1(n1) { return n1 + 42; }, /** @type {string} */ lol, /** @type {number} */ ['b' + 'ar1']: 42, /** @type {function(number): number} */ arrowFunc: (num) => num + 42} : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>{ /** @type {string|undefined} */ foo: undefined, /** @type {string|undefined} */ bar: "42", /** @type {function(number): number} */ method1(n1) { return n1 + 42; }, /** @type {string} */ lol, /** @type {number} */ ['b' + 'ar1']: 42, /** @type {function(number): number} */ arrowFunc: (num) => num + 42} : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
/** @type {string|undefined} */
foo: undefined,
@@ -53,19 +53,19 @@ const obj = {
obj.foo = 'string'
>obj.foo = 'string' : "string"
>obj.foo : string | undefined
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>foo : string | undefined
>'string' : "string"
obj.lol
>obj.lol : string
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>lol : string
obj.bar = undefined;
>obj.bar = undefined : undefined
>obj.bar : string | undefined
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>bar : string | undefined
>undefined : undefined
@@ -73,21 +73,21 @@ var k = obj.method1(0);
>k : number
>obj.method1(0) : number
>obj.method1 : (arg0: number) => number
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>method1 : (arg0: number) => number
>0 : 0
obj.bar1 = "42";
>obj.bar1 = "42" : "42"
>obj.bar1 : any
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>bar1 : any
>obj.bar1 : string | number | ((arg0: number) => number) | undefined
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>bar1 : string | number | ((arg0: number) => number) | undefined
>"42" : "42"
obj.arrowFunc(0);
>obj.arrowFunc(0) : number
>obj.arrowFunc : (arg0: number) => number
>obj : { [x: string]: any; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>obj : { [x: string]: string | number | ((arg0: number) => number) | undefined; foo: string | undefined; bar: string | undefined; method1(arg0: number): number; lol: string; arrowFunc: (arg0: number) => number; }
>arrowFunc : (arg0: number) => number
>0 : 0

View File

@@ -4,8 +4,8 @@ var lol;
>lol : any
const obj = {
>obj : { [x: string]: any; bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>{ /** @type {string|undefined} */ bar: 42, /** @type {function(number): number} */ method1(n1) { return "42"; }, /** @type {function(number): number} */ method2: (n1) => "lol", /** @type {function(number): number} */ arrowFunc: (num="0") => num + 42, /** @type {string} */ lol} : { [x: string]: any; bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>obj : { bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>{ /** @type {string|undefined} */ bar: 42, /** @type {function(number): number} */ method1(n1) { return "42"; }, /** @type {function(number): number} */ method2: (n1) => "lol", /** @type {function(number): number} */ arrowFunc: (num="0") => num + 42, /** @type {string} */ lol} : { bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
/** @type {string|undefined} */
bar: 42,
@@ -52,7 +52,7 @@ var s = obj.method1(0);
>s : string
>obj.method1(0) : number
>obj.method1 : (arg0: number) => number
>obj : { [x: string]: any; bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>obj : { bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>method1 : (arg0: number) => number
>0 : 0
@@ -61,7 +61,7 @@ var s1 = obj.method2("0");
>s1 : string
>obj.method2("0") : number
>obj.method2 : (arg0: number) => number
>obj : { [x: string]: any; bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>obj : { bar: string | undefined; method1(arg0: number): number; method2: (arg0: number) => number; arrowFunc: (arg0: number) => number; lol: string; }
>method2 : (arg0: number) => number
>"0" : "0"

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/bug24252.js ===
var A = {};
>A : typeof A
>{} : { [x: string]: any; }
>{} : {}
A.B = class {
>A.B = class { m() { /** @type {string[]} */ var x = []; /** @type {number[]} */ var y; y = x; }} : typeof B

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/types/thisType/context.js ===
const obj = {
>obj : { [x: string]: any; prop: number; method(): void; }
>{ prop: 2, method() { this; this.prop; this.method; this.unknown; // ok, obj has a string indexer }} : { [x: string]: any; prop: number; method(): void; }
>obj : { prop: number; method(): void; }
>{ prop: 2, method() { this; this.prop; this.method; this.unknown; // ok, obj has a string indexer }} : { prop: number; method(): void; }
prop: 2,
>prop : number
@@ -11,21 +11,21 @@ const obj = {
>method : () => void
this;
>this : { [x: string]: any; prop: number; method(): void; }
>this : { prop: number; method(): void; }
this.prop;
>this.prop : number
>this : { [x: string]: any; prop: number; method(): void; }
>this : { prop: number; method(): void; }
>prop : number
this.method;
>this.method : () => void
>this : { [x: string]: any; prop: number; method(): void; }
>this : { prop: number; method(): void; }
>method : () => void
this.unknown; // ok, obj has a string indexer
>this.unknown : any
>this : { [x: string]: any; prop: number; method(): void; }
>this : { prop: number; method(): void; }
>unknown : any
}
}

View File

@@ -6,14 +6,14 @@
// property assignment
var ns = {}
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
>{} : { [x: string]: any; }
>ns : { x: { status: "done"; m(n: number): void; }; }
>{} : {}
/** @type {DoneStatus} */
ns.x = {
>ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
>ns.x : { status: "done"; m(n: number): void; }
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
>ns : { x: { status: "done"; m(n: number): void; }; }
>x : { status: "done"; m(n: number): void; }
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
@@ -29,7 +29,7 @@ ns.x = {
ns.x = {
>ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
>ns.x : { status: "done"; m(n: number): void; }
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
>ns : { x: { status: "done"; m(n: number): void; }; }
>x : { status: "done"; m(n: number): void; }
>{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; }
@@ -43,7 +43,7 @@ ns.x = {
}
ns.x
>ns.x : { status: "done"; m(n: number): void; }
>ns : { [x: string]: any; x: { status: "done"; m(n: number): void; }; }
>ns : { x: { status: "done"; m(n: number): void; }; }
>x : { status: "done"; m(n: number): void; }

View File

@@ -1,8 +1,8 @@
=== tests/cases/compiler/foo.js ===
// Repro for #16585
const x = {
>x : { [x: string]: any; bar(): void; }
>{ bar() { setTimeout(function() { arguments }, 0); }} : { [x: string]: any; bar(): void; }
>x : { bar(): void; }
>{ bar() { setTimeout(function() { arguments }, 0); }} : { bar(): void; }
bar() {
>bar : () => void

View File

@@ -1,10 +1,10 @@
=== tests/cases/compiler/a.js ===
const Obj = {};
>Obj : { [x: string]: any; }
>{} : { [x: string]: any; }
>Obj : {}
>{} : {}
export default Obj;
>Obj : { [x: string]: any; }
>Obj : {}
=== tests/cases/compiler/b.js ===
import Obj from './a';

View File

@@ -4,7 +4,7 @@ exports.n = {};
>exports.n : typeof n
>exports : typeof import("tests/cases/conformance/salsa/mod")
>n : typeof n
>{} : { [x: string]: any; }
>{} : {}
exports.n.K = function () {
>exports.n.K = function () { this.x = 10;} : typeof K

View File

@@ -1,11 +1,11 @@
=== tests/cases/conformance/salsa/mod.js ===
// Based on a pattern from adonis
exports.formatters = {}
>exports.formatters = {} : { [x: string]: any; }
>exports.formatters : { [x: string]: any; }
>exports.formatters = {} : {}
>exports.formatters : {}
>exports : typeof import("tests/cases/conformance/salsa/mod")
>formatters : { [x: string]: any; }
>{} : { [x: string]: any; }
>formatters : {}
>{} : {}
=== tests/cases/conformance/salsa/first.js ===
exports = require('./mod')
@@ -56,18 +56,18 @@ import * as debug from './mod'
debug.formatters.j
>debug.formatters.j : any
>debug.formatters : { [x: string]: any; }
>debug.formatters : {}
>debug : typeof debug
>formatters : { [x: string]: any; }
>formatters : {}
>j : any
var one = debug.formatters.o(1)
>one : any
>debug.formatters.o(1) : any
>debug.formatters.o : any
>debug.formatters : { [x: string]: any; }
>debug.formatters : {}
>debug : typeof debug
>formatters : { [x: string]: any; }
>formatters : {}
>o : any
>1 : 1

View File

@@ -21,8 +21,8 @@ var e = new exports.E();
>E : typeof E
var o = {
>o : { [x: string]: any; C: typeof C; }
>{ C: function () { this.c = 'nested object' }} : { [x: string]: any; C: typeof C; }
>o : { C: typeof C; }
>{ C: function () { this.c = 'nested object' }} : { C: typeof C; }
C: function () {
>C : typeof C
@@ -31,7 +31,7 @@ var o = {
this.c = 'nested object'
>this.c = 'nested object' : "nested object"
>this.c : any
>this : { [x: string]: any; C: typeof C; }
>this : { C: typeof C; }
>c : any
>'nested object' : "nested object"
}
@@ -40,7 +40,7 @@ var og = new o.C();
>og : C
>new o.C() : C
>o.C : typeof C
>o : { [x: string]: any; C: typeof C; }
>o : { C: typeof C; }
>C : typeof C
var V = function () {

View File

@@ -2,22 +2,22 @@
// #24131
const a = {};
>a : typeof a
>{} : { [x: string]: any; }
>{} : {}
a.d = function() {};
>a.d = function() {} : { (): void; prototype: { [x: string]: any; }; }
>a.d : { (): void; prototype: { [x: string]: any; }; }
>a.d = function() {} : { (): void; prototype: {}; }
>a.d : { (): void; prototype: {}; }
>a : typeof a
>d : { (): void; prototype: { [x: string]: any; }; }
>function() {} : { (): void; prototype: { [x: string]: any; }; }
>d : { (): void; prototype: {}; }
>function() {} : { (): void; prototype: {}; }
=== tests/cases/conformance/salsa/b.js ===
a.d.prototype = {};
>a.d.prototype = {} : { [x: string]: any; }
>a.d.prototype : { [x: string]: any; }
>a.d : { (): void; prototype: { [x: string]: any; }; }
>a.d.prototype = {} : {}
>a.d.prototype : {}
>a.d : { (): void; prototype: {}; }
>a : typeof a
>d : { (): void; prototype: { [x: string]: any; }; }
>prototype : { [x: string]: any; }
>{} : { [x: string]: any; }
>d : { (): void; prototype: {}; }
>prototype : {}
>{} : {}

View File

@@ -7,11 +7,11 @@ declare namespace C {
}
=== tests/cases/conformance/salsa/b.js ===
C.prototype = {};
>C.prototype = {} : { [x: string]: any; }
>C.prototype : { [x: string]: any; }
>C.prototype = {} : {}
>C.prototype : {}
>C : typeof C
>prototype : { [x: string]: any; }
>{} : { [x: string]: any; }
>prototype : {}
>{} : {}
C.bar = 2;
>C.bar = 2 : 2

View File

@@ -5,12 +5,12 @@ declare class A {}
=== tests/cases/conformance/salsa/b.js ===
const A = { };
>A : typeof A
>{ } : { [x: string]: any; }
>{ } : {}
A.d = { };
>A.d = { } : { [x: string]: any; }
>A.d : { [x: string]: any; }
>A.d = { } : {}
>A.d : {}
>A : typeof A
>d : { [x: string]: any; }
>{ } : { [x: string]: any; }
>d : {}
>{ } : {}

View File

@@ -1,16 +1,16 @@
=== tests/cases/compiler/foo.js ===
module.exports = function () {
>module.exports = function () { class A { } return { c: A.b = 1, }} : () => { [x: string]: any; c: number; }
>module.exports : () => { [x: string]: any; c: number; }
>module : { "tests/cases/compiler/foo": () => { [x: string]: any; c: number; }; }
>exports : () => { [x: string]: any; c: number; }
>function () { class A { } return { c: A.b = 1, }} : () => { [x: string]: any; c: number; }
>module.exports = function () { class A { } return { c: A.b = 1, }} : () => { c: number; }
>module.exports : () => { c: number; }
>module : { "tests/cases/compiler/foo": () => { c: number; }; }
>exports : () => { c: number; }
>function () { class A { } return { c: A.b = 1, }} : () => { c: number; }
class A { }
>A : A
return {
>{ c: A.b = 1, } : { [x: string]: any; c: number; }
>{ c: A.b = 1, } : { c: number; }
c: A.b = 1,
>c : number

View File

@@ -3,8 +3,8 @@
>"use strict" : "use strict"
var a = {
>a : { [x: string]: any; a: number; b: number; }
>{ a: "hello", // error b: 10, a: 10 // error} : { [x: string]: any; a: number; b: number; }
>a : { a: number; b: number; }
>{ a: "hello", // error b: 10, a: 10 // error} : { a: number; b: number; }
a: "hello", // error
>a : string
@@ -25,7 +25,7 @@ var let = 10; // error
delete a; // error
>delete a : boolean
>a : { [x: string]: any; a: number; b: number; }
>a : { a: number; b: number; }
try {
} catch (eval) { // error
@@ -36,7 +36,7 @@ function arguments() { // error
}
with (a) {
>a : { [x: string]: any; a: number; b: number; }
>a : { a: number; b: number; }
b = 10;
>b = 10 : any

View File

@@ -1,6 +1,6 @@
=== tests/cases/compiler/a.js ===
function foo() {
>foo : () => { [x: string]: any; a: number; b: string; }
>foo : () => { a: number; b: string; }
var a = 10;
>a : number
@@ -11,7 +11,7 @@ function foo() {
>"Hello" : "Hello"
return {
>{ a, b } : { [x: string]: any; a: number; b: string; }
>{ a, b } : { a: number; b: string; }
a,
>a : number

View File

@@ -1,12 +1,12 @@
=== tests/cases/conformance/salsa/a.js ===
var variable = {};
>variable : { [x: string]: any; a: number; }
>{} : { [x: string]: any; }
>variable : { a: number; }
>{} : {}
variable.a = 0;
>variable.a = 0 : 0
>variable.a : number
>variable : { [x: string]: any; a: number; }
>variable : { a: number; }
>a : number
>0 : 0
@@ -14,57 +14,57 @@ class C {
>C : C
initializedMember = {};
>initializedMember : { [x: string]: any; }
>{} : { [x: string]: any; }
>initializedMember : {}
>{} : {}
constructor() {
this.member = {};
>this.member = {} : { [x: string]: any; }
>this.member : { [x: string]: any; }
>this.member = {} : {}
>this.member : {}
>this : this
>member : { [x: string]: any; }
>{} : { [x: string]: any; }
>member : {}
>{} : {}
this.member.a = 0;
>this.member.a = 0 : 0
>this.member.a : any
>this.member : { [x: string]: any; }
>this.member : {}
>this : this
>member : { [x: string]: any; }
>member : {}
>a : any
>0 : 0
}
}
var obj = {
>obj : { [x: string]: any; property: { [x: string]: any; }; }
>{ property: {}} : { [x: string]: any; property: { [x: string]: any; }; }
>obj : { property: {}; }
>{ property: {}} : { property: {}; }
property: {}
>property : { [x: string]: any; }
>{} : { [x: string]: any; }
>property : {}
>{} : {}
};
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; }
>obj.property : {}
>obj : { property: {}; }
>property : {}
>a : any
>0 : 0
var arr = [{}];
>arr : { [x: string]: any; }[]
>[{}] : { [x: string]: any; }[]
>{} : { [x: string]: any; }
>arr : {}[]
>[{}] : {}[]
>{} : {}
function getObj() {
>getObj : () => { [x: string]: any; }
>getObj : () => {}
return {};
>{} : { [x: string]: any; }
>{} : {}
}
@@ -72,46 +72,46 @@ function getObj() {
variable.a = 1;
>variable.a = 1 : 1
>variable.a : number
>variable : { [x: string]: any; a: number; }
>variable : { a: number; }
>a : number
>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()).member : {}
>(new C()) : C
>new C() : C
>C : typeof C
>member : { [x: string]: any; }
>member : {}
>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()).initializedMember : {}
>(new C()) : C
>new C() : C
>C : typeof C
>initializedMember : { [x: string]: any; }
>initializedMember : {}
>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; }
>obj.property : {}
>obj : { property: {}; }
>property : {}
>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; }[]
>arr[0] : {}
>arr : {}[]
>0 : 0
>a : any
>1 : 1
@@ -119,8 +119,8 @@ arr[0].a = 1;
getObj().a = 1;
>getObj().a = 1 : 1
>getObj().a : any
>getObj() : { [x: string]: any; }
>getObj : () => { [x: string]: any; }
>getObj() : {}
>getObj : () => {}
>a : any
>1 : 1

View File

@@ -1,7 +1,7 @@
=== /a.js ===
const o = {
>o : { [x: string]: any; a(): void; }
>{ a() { // Should not be treated as a declaration. Should be an error. this.a = 0; }} : { [x: string]: any; a(): void; }
>o : { a(): void; }
>{ a() { // Should not be treated as a declaration. Should be an error. this.a = 0; }} : { a(): void; }
a() {
>a : () => void
@@ -10,7 +10,7 @@ const o = {
this.a = 0;
>this.a = 0 : 0
>this.a : () => void
>this : { [x: string]: any; a(): void; }
>this : { a(): void; }
>a : () => void
>0 : 0
}

View File

@@ -1,7 +1,7 @@
=== /a.js ===
const o = {
>o : { [x: string]: any; a(): void; }
>{ a() { // Should not be treated as a declaration. this.a = () => {}; }} : { [x: string]: any; a(): void; }
>o : { a(): void; }
>{ a() { // Should not be treated as a declaration. this.a = () => {}; }} : { a(): void; }
a() {
>a : () => void
@@ -10,7 +10,7 @@ const o = {
this.a = () => {};
>this.a = () => {} : () => void
>this.a : () => void
>this : { [x: string]: any; a(): void; }
>this : { a(): void; }
>a : () => void
>() => {} : () => void
}

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/jsdoc/github17339.js ===
var obj = {
>obj : { [x: string]: any; x: <T>(a: T) => T; }
>{ /** * @template T * @param {T} a * @returns {T} */ x: function (a) { return a; },} : { [x: string]: any; x: <T>(a: T) => T; }
>obj : { x: <T>(a: T) => T; }
>{ /** * @template T * @param {T} a * @returns {T} */ x: function (a) { return a; },} : { x: <T>(a: T) => T; }
/**
* @template T

View File

@@ -4,11 +4,11 @@ class C {
>C : C
}
module.exports = {
>module.exports = { C} : { [x: string]: any; C: typeof C; }
>module.exports : { [x: string]: any; C: typeof C; }
>module : { "tests/cases/conformance/salsa/bug24062": { [x: string]: any; C: typeof C; }; }
>exports : { [x: string]: any; C: typeof C; }
>{ C} : { [x: string]: any; C: typeof C; }
>module.exports = { C} : { C: typeof C; }
>module.exports : { C: typeof C; }
>module : { "tests/cases/conformance/salsa/bug24062": { C: typeof C; }; }
>exports : { C: typeof C; }
>{ C} : { C: typeof C; }
C
>C : typeof C

View File

@@ -1,10 +1,10 @@
=== tests/cases/conformance/salsa/async.js ===
exports.default = { m: 1, a: 1 }
>exports.default = { m: 1, a: 1 } : { [x: string]: any; m: number; a: number; }
>exports.default = { m: 1, a: 1 } : { m: number; a: number; }
>exports.default : any
>exports : any
>default : any
>{ m: 1, a: 1 } : { [x: string]: any; m: number; a: number; }
>{ m: 1, a: 1 } : { m: number; a: number; }
>m : number
>1 : 1
>a : number

View File

@@ -6,7 +6,7 @@ module.exports.n = {};
>module : { "tests/cases/conformance/salsa/mod": typeof import("tests/cases/conformance/salsa/mod"); }
>exports : typeof import("tests/cases/conformance/salsa/mod")
>n : typeof n
>{} : { [x: string]: any; }
>{} : {}
module.exports.n.K = function C() {
>module.exports.n.K = function C() { this.x = 10;} : typeof C

View File

@@ -1,21 +1,21 @@
=== tests/cases/conformance/salsa/axios.js ===
var axios = {}
>axios : { [x: string]: any; default: { [x: string]: any; default: any; }; }
>{} : { [x: string]: any; }
>axios : { default: { default: any; }; }
>{} : {}
module.exports = axios // both assignments should be ok
>module.exports = axios : { [x: string]: any; default: any; }
>module.exports : { [x: string]: any; default: any; }
>module : { "tests/cases/conformance/salsa/axios": { [x: string]: any; default: any; }; }
>exports : { [x: string]: any; default: any; }
>axios : { [x: string]: any; default: { [x: string]: any; default: any; }; }
>module.exports = axios : { default: any; }
>module.exports : { default: any; }
>module : { "tests/cases/conformance/salsa/axios": { default: any; }; }
>exports : { default: any; }
>axios : { default: { default: any; }; }
module.exports.default = axios
>module.exports.default = axios : { [x: string]: any; default: { [x: string]: any; default: any; }; }
>module.exports.default : { [x: string]: any; default: any; }
>module.exports : { [x: string]: any; default: any; }
>module : { "tests/cases/conformance/salsa/axios": { [x: string]: any; default: any; }; }
>exports : { [x: string]: any; default: any; }
>default : { [x: string]: any; default: any; }
>axios : { [x: string]: any; default: { [x: string]: any; default: any; }; }
>module.exports.default = axios : { default: { default: any; }; }
>module.exports.default : { default: any; }
>module.exports : { default: any; }
>module : { "tests/cases/conformance/salsa/axios": { default: any; }; }
>exports : { default: any; }
>default : { default: any; }
>axios : { default: { default: any; }; }

View File

@@ -1,8 +1,8 @@
=== tests/cases/conformance/salsa/a.js ===
/// <reference path='./requires.d.ts' />
var mod1 = require('./mod1')
>mod1 : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>require('./mod1') : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>mod1 : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>require('./mod1') : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>require : (name: string) => any
>'./mod1' : "./mod1"
@@ -10,7 +10,7 @@ mod1.justExport.toFixed()
>mod1.justExport.toFixed() : string
>mod1.justExport.toFixed : (fractionDigits?: number) => string
>mod1.justExport : number
>mod1 : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>mod1 : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>justExport : number
>toFixed : (fractionDigits?: number) => string
@@ -18,7 +18,7 @@ mod1.bothBefore.toFixed() // error, 'toFixed' not on 'string | number'
>mod1.bothBefore.toFixed() : any
>mod1.bothBefore.toFixed : any
>mod1.bothBefore : string | number
>mod1 : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>mod1 : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>bothBefore : string | number
>toFixed : any
@@ -26,14 +26,14 @@ mod1.bothAfter.toFixed() // error, 'toFixed' not on 'string | number'
>mod1.bothAfter.toFixed() : any
>mod1.bothAfter.toFixed : any
>mod1.bothAfter : string | number
>mod1 : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>mod1 : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>bothAfter : string | number
>toFixed : any
mod1.justProperty.length
>mod1.justProperty.length : number
>mod1.justProperty : string
>mod1 : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>mod1 : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>justProperty : string
>length : number
@@ -51,18 +51,18 @@ declare function require(name: string): any;
module.exports.bothBefore = 'string'
>module.exports.bothBefore = 'string' : "string"
>module.exports.bothBefore : string | number
>module.exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module.exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>bothBefore : string | number
>'string' : "string"
module.exports = {
>module.exports = { justExport: 1, bothBefore: 2, bothAfter: 3,} : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module.exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>{ justExport: 1, bothBefore: 2, bothAfter: 3,} : { [x: string]: any; justExport: number; bothBefore: number; bothAfter: number; }
>module.exports = { justExport: 1, bothBefore: 2, bothAfter: 3,} : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module.exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>{ justExport: 1, bothBefore: 2, bothAfter: 3,} : { justExport: number; bothBefore: number; bothAfter: number; }
justExport: 1,
>justExport : number
@@ -79,18 +79,18 @@ module.exports = {
module.exports.bothAfter = 'string'
>module.exports.bothAfter = 'string' : "string"
>module.exports.bothAfter : string | number
>module.exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module.exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>bothAfter : string | number
>'string' : "string"
module.exports.justProperty = 'string'
>module.exports.justProperty = 'string' : "string"
>module.exports.justProperty : string
>module.exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { [x: string]: any; justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module.exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>module : { "tests/cases/conformance/salsa/mod1": { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }; }
>exports : { justExport: number; bothBefore: string | number; bothAfter: string | number; justProperty: string; }
>justProperty : string
>'string' : "string"

View File

@@ -5,16 +5,16 @@ C.prototype = {}
>C.prototype : typeof C.prototype
>C : typeof C
>prototype : typeof C.prototype
>{} : { [x: string]: any; }
>{} : {}
C.prototype.bar.foo = {};
>C.prototype.bar.foo = {} : { [x: string]: any; }
>C.prototype.bar.foo : { [x: string]: any; }
>C.prototype.bar.foo = {} : {}
>C.prototype.bar.foo : {}
>C.prototype.bar : typeof C.prototype.bar
>C.prototype : typeof C.prototype
>C : typeof C
>prototype : typeof C.prototype
>bar : typeof C.prototype.bar
>foo : { [x: string]: any; }
>{} : { [x: string]: any; }
>foo : {}
>{} : {}

View File

@@ -1,16 +1,16 @@
=== tests/cases/conformance/salsa/mod1.js ===
export var hurk = {}
>hurk : { [x: string]: any; }
>{} : { [x: string]: any; }
>hurk : {}
>{} : {}
=== tests/cases/conformance/salsa/bug24658.js ===
import { hurk } from './mod1'
>hurk : { [x: string]: any; }
>hurk : {}
hurk.expando = 4
>hurk.expando = 4 : 4
>hurk.expando : any
>hurk : { [x: string]: any; }
>hurk : {}
>expando : any
>4 : 4

View File

@@ -18,8 +18,8 @@ function f(s) {
}
const o = {
>o : { [x: string]: any; f: (s: string) => number; n: number; }
>{ f, n: 1} : { [x: string]: any; f: (s: string) => number; n: number; }
>o : { f: (s: string) => number; n: number; }
>{ f, n: 1} : { f: (s: string) => number; n: number; }
f,
>f : (s: string) => number
@@ -31,7 +31,7 @@ const o = {
o.f('hi')
>o.f('hi') : number
>o.f : (s: string) => number
>o : { [x: string]: any; f: (s: string) => number; n: number; }
>o : { f: (s: string) => number; n: number; }
>f : (s: string) => number
>'hi' : "hi"

View File

@@ -44,11 +44,11 @@ a.unknown = true
>true : true
a.unknown = {}
>a.unknown = {} : { [x: string]: any; }
>a.unknown = {} : {}
>a.unknown : any
>a : A
>unknown : any
>{} : { [x: string]: any; }
>{} : {}
a.unknown = 'hi'
>a.unknown = 'hi' : "hi"
@@ -72,11 +72,11 @@ a.unknowable = true
>true : true
a.unknowable = {}
>a.unknowable = {} : { [x: string]: any; }
>a.unknowable = {} : {}
>a.unknowable : any
>a : A
>unknowable : any
>{} : { [x: string]: any; }
>{} : {}
a.unknowable = 'hi'
>a.unknowable = 'hi' : "hi"

View File

@@ -1,20 +1,20 @@
=== tests/cases/conformance/salsa/module.js ===
var Outer = Outer || {};
>Outer : typeof Outer
>Outer || {} : typeof Outer | { [x: string]: any; }
>Outer || {} : typeof Outer | {}
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
Outer.app = Outer.app || {};
>Outer.app = Outer.app || {} : typeof Outer.app
>Outer.app : typeof Outer.app
>Outer : typeof Outer
>app : typeof Outer.app
>Outer.app || {} : { [x: string]: any; }
>Outer.app || {} : {}
>Outer.app : typeof Outer.app
>Outer : typeof Outer
>app : typeof Outer.app
>{} : { [x: string]: any; }
>{} : {}
=== tests/cases/conformance/salsa/someview.js ===
Outer.app.SomeView = (function () {

View File

@@ -4,11 +4,11 @@ var Inner = function() {}
>function() {} : typeof Inner
Inner.prototype = {
>Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
>Inner.prototype : { [x: string]: any; m(): void; i: number; }
>Inner.prototype = { m() { }, i: 1} : { m(): void; i: number; }
>Inner.prototype : { m(): void; i: number; }
>Inner : typeof Inner
>prototype : { [x: string]: any; m(): void; i: number; }
>{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
>prototype : { m(): void; i: number; }
>{ m() { }, i: 1} : { m(): void; i: number; }
m() { },
>m : () => void
@@ -21,43 +21,43 @@ Inner.prototype = {
Inner.prototype.j = 2
>Inner.prototype.j = 2 : 2
>Inner.prototype.j : any
>Inner.prototype : { [x: string]: any; m(): void; i: number; }
>Inner.prototype : { m(): void; i: number; }
>Inner : typeof Inner
>prototype : { [x: string]: any; m(): void; i: number; }
>prototype : { m(): void; i: number; }
>j : any
>2 : 2
/** @type {string} */
Inner.prototype.k;
>Inner.prototype.k : any
>Inner.prototype : { [x: string]: any; m(): void; i: number; }
>Inner.prototype : { m(): void; i: number; }
>Inner : typeof Inner
>prototype : { [x: string]: any; m(): void; i: number; }
>prototype : { m(): void; i: number; }
>k : any
var inner = new Inner()
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>new Inner() : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>new Inner() : Inner & { m(): void; i: number; }
>Inner : typeof Inner
inner.m()
>inner.m() : void
>inner.m : () => void
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>m : () => void
inner.i
>inner.i : number
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>i : number
inner.j
>inner.j : number
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>j : number
inner.k
>inner.k : string
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>k : string

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/module.js ===
var Outer = {}
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
Outer.Inner = function() {}
>Outer.Inner = function() {} : typeof Inner
@@ -11,13 +11,13 @@ Outer.Inner = function() {}
>function() {} : typeof Inner
Outer.Inner.prototype = {
>Outer.Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; }
>Outer.Inner.prototype = { m() { }, i: 1} : { m(): void; i: number; }
>Outer.Inner.prototype : { m(): void; i: number; }
>Outer.Inner : typeof Inner
>Outer : typeof Outer
>Inner : typeof Inner
>prototype : { [x: string]: any; m(): void; i: number; }
>{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; }
>prototype : { m(): void; i: number; }
>{ m() { }, i: 1} : { m(): void; i: number; }
m() { },
>m : () => void
@@ -30,27 +30,27 @@ Outer.Inner.prototype = {
Outer.Inner.prototype.j = 2
>Outer.Inner.prototype.j = 2 : 2
>Outer.Inner.prototype.j : any
>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; }
>Outer.Inner.prototype : { m(): void; i: number; }
>Outer.Inner : typeof Inner
>Outer : typeof Outer
>Inner : typeof Inner
>prototype : { [x: string]: any; m(): void; i: number; }
>prototype : { m(): void; i: number; }
>j : any
>2 : 2
/** @type {string} */
Outer.Inner.prototype.k;
>Outer.Inner.prototype.k : any
>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; }
>Outer.Inner.prototype : { m(): void; i: number; }
>Outer.Inner : typeof Inner
>Outer : typeof Outer
>Inner : typeof Inner
>prototype : { [x: string]: any; m(): void; i: number; }
>prototype : { m(): void; i: number; }
>k : any
var inner = new Outer.Inner()
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>new Outer.Inner() : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>new Outer.Inner() : Inner & { m(): void; i: number; }
>Outer.Inner : typeof Inner
>Outer : typeof Outer
>Inner : typeof Inner
@@ -58,21 +58,21 @@ var inner = new Outer.Inner()
inner.m()
>inner.m() : void
>inner.m : () => void
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>m : () => void
inner.i
>inner.i : number
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>i : number
inner.j
>inner.j : number
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>j : number
inner.k
>inner.k : string
>inner : Inner & { [x: string]: any; m(): void; i: number; }
>inner : Inner & { m(): void; i: number; }
>k : string

View File

@@ -1,24 +1,24 @@
=== tests/cases/conformance/salsa/def.js ===
var Outer = {};
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
=== tests/cases/conformance/salsa/work.js ===
Outer.Inner = function () {}
>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Outer.Inner = function () {} : { (): void; prototype: { x: number; m(): void; }; }
>Outer.Inner : { (): void; prototype: { x: number; m(): void; }; }
>Outer : typeof Outer
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Inner : { (): void; prototype: { x: number; m(): void; }; }
>function () {} : { (): void; prototype: { x: number; m(): void; }; }
Outer.Inner.prototype = {
>Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
>Outer.Inner.prototype : { [x: string]: any; x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Outer.Inner.prototype = { x: 1, m() { }} : { x: number; m(): void; }
>Outer.Inner.prototype : { x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { x: number; m(): void; }; }
>Outer : typeof Outer
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>prototype : { [x: string]: any; x: number; m(): void; }
>{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
>Inner : { (): void; prototype: { x: number; m(): void; }; }
>prototype : { x: number; m(): void; }
>{ x: 1, m() { }} : { x: number; m(): void; }
x: 1,
>x : number
@@ -31,35 +31,35 @@ Outer.Inner.prototype = {
=== tests/cases/conformance/salsa/use.js ===
/** @type {Outer.Inner} */
var inner
>inner : { [x: string]: any; x: number; m(): void; }
>inner : { x: number; m(): void; }
inner.x
>inner.x : number
>inner : { [x: string]: any; x: number; m(): void; }
>inner : { x: number; m(): void; }
>x : number
inner.m()
>inner.m() : void
>inner.m : () => void
>inner : { [x: string]: any; x: number; m(): void; }
>inner : { x: number; m(): void; }
>m : () => void
var inno = new Outer.Inner()
>inno : { [x: string]: any; x: number; m(): void; }
>new Outer.Inner() : { [x: string]: any; x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>inno : { x: number; m(): void; }
>new Outer.Inner() : { x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { x: number; m(): void; }; }
>Outer : typeof Outer
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Inner : { (): void; prototype: { x: number; m(): void; }; }
inno.x
>inno.x : number
>inno : { [x: string]: any; x: number; m(): void; }
>inno : { x: number; m(): void; }
>x : number
inno.m()
>inno.m() : void
>inno.m : () => void
>inno : { [x: string]: any; x: number; m(): void; }
>inno : { x: number; m(): void; }
>m : () => void

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/a.js ===
var Outer = {};
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
Outer.Inner = class {
>Outer.Inner = class { constructor() { this.x = 1 } m() { }} : typeof Inner

View File

@@ -1,23 +1,23 @@
=== tests/cases/conformance/salsa/a.js ===
var Outer = {};
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
Outer.Inner = function () {}
>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Outer.Inner = function () {} : { (): void; prototype: { x: number; m(): void; }; }
>Outer.Inner : { (): void; prototype: { x: number; m(): void; }; }
>Outer : typeof Outer
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Inner : { (): void; prototype: { x: number; m(): void; }; }
>function () {} : { (): void; prototype: { x: number; m(): void; }; }
Outer.Inner.prototype = {
>Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
>Outer.Inner.prototype : { [x: string]: any; x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Outer.Inner.prototype = { x: 1, m() { }} : { x: number; m(): void; }
>Outer.Inner.prototype : { x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { x: number; m(): void; }; }
>Outer : typeof Outer
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>prototype : { [x: string]: any; x: number; m(): void; }
>{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; }
>Inner : { (): void; prototype: { x: number; m(): void; }; }
>prototype : { x: number; m(): void; }
>{ x: 1, m() { }} : { x: number; m(): void; }
x: 1,
>x : number
@@ -29,34 +29,34 @@ Outer.Inner.prototype = {
/** @type {Outer.Inner} */
var inner
>inner : { [x: string]: any; x: number; m(): void; }
>inner : { x: number; m(): void; }
inner.x
>inner.x : number
>inner : { [x: string]: any; x: number; m(): void; }
>inner : { x: number; m(): void; }
>x : number
inner.m()
>inner.m() : void
>inner.m : () => void
>inner : { [x: string]: any; x: number; m(): void; }
>inner : { x: number; m(): void; }
>m : () => void
var inno = new Outer.Inner()
>inno : { [x: string]: any; x: number; m(): void; }
>new Outer.Inner() : { [x: string]: any; x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>inno : { x: number; m(): void; }
>new Outer.Inner() : { x: number; m(): void; }
>Outer.Inner : { (): void; prototype: { x: number; m(): void; }; }
>Outer : typeof Outer
>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }
>Inner : { (): void; prototype: { x: number; m(): void; }; }
inno.x
>inno.x : number
>inno : { [x: string]: any; x: number; m(): void; }
>inno : { x: number; m(): void; }
>x : number
inno.m()
>inno.m() : void
>inno.m : () => void
>inno : { [x: string]: any; x: number; m(): void; }
>inno : { x: number; m(): void; }
>m : () => void

View File

@@ -1,52 +1,52 @@
=== tests/cases/conformance/salsa/a.js ===
var GLOBSTAR = m.GLOBSTAR = {}
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m.GLOBSTAR = {} : { [x: string]: any; q: number; p: number; }
>m.GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m : { (): void; GLOBSTAR: { [x: string]: any; q: number; p: number; }; }
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>{} : { [x: string]: any; }
>GLOBSTAR : { q: number; p: number; }
>m.GLOBSTAR = {} : { q: number; p: number; }
>m.GLOBSTAR : { q: number; p: number; }
>m : { (): void; GLOBSTAR: { q: number; p: number; }; }
>GLOBSTAR : { q: number; p: number; }
>{} : {}
function m() {
>m : { (): void; GLOBSTAR: { [x: string]: any; q: number; p: number; }; }
>m : { (): void; GLOBSTAR: { q: number; p: number; }; }
}
GLOBSTAR.p = 1
>GLOBSTAR.p = 1 : 1
>GLOBSTAR.p : number
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>GLOBSTAR : { q: number; p: number; }
>p : number
>1 : 1
m.GLOBSTAR.q = 2
>m.GLOBSTAR.q = 2 : 2
>m.GLOBSTAR.q : number
>m.GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m : { (): void; GLOBSTAR: { [x: string]: any; q: number; p: number; }; }
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m.GLOBSTAR : { q: number; p: number; }
>m : { (): void; GLOBSTAR: { q: number; p: number; }; }
>GLOBSTAR : { q: number; p: number; }
>q : number
>2 : 2
GLOBSTAR.p
>GLOBSTAR.p : number
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>GLOBSTAR : { q: number; p: number; }
>p : number
GLOBSTAR.q
>GLOBSTAR.q : number
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>GLOBSTAR : { q: number; p: number; }
>q : number
m.GLOBSTAR.p
>m.GLOBSTAR.p : number
>m.GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m : { (): void; GLOBSTAR: { [x: string]: any; q: number; p: number; }; }
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m.GLOBSTAR : { q: number; p: number; }
>m : { (): void; GLOBSTAR: { q: number; p: number; }; }
>GLOBSTAR : { q: number; p: number; }
>p : number
m.GLOBSTAR.q
>m.GLOBSTAR.q : number
>m.GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m : { (): void; GLOBSTAR: { [x: string]: any; q: number; p: number; }; }
>GLOBSTAR : { [x: string]: any; q: number; p: number; }
>m.GLOBSTAR : { q: number; p: number; }
>m : { (): void; GLOBSTAR: { q: number; p: number; }; }
>GLOBSTAR : { q: number; p: number; }
>q : number

View File

@@ -35,7 +35,7 @@ x.name
=== tests/cases/conformance/salsa/def.js ===
var Outer = {}
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
Outer.Inner = class {
>Outer.Inner = class { name() { return 'hi' }} : typeof Inner

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/bug24703.js ===
var Common = {};
>Common : typeof Common
>{} : { [x: string]: any; }
>{} : {}
Common.I = class {
>Common.I = class { constructor() { this.i = 1 }} : typeof I

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/bug24730.js ===
var UI = {}
>UI : typeof UI
>{} : { [x: string]: any; }
>{} : {}
UI.TreeElement = class {
>UI.TreeElement = class { constructor() { this.treeOutline = 12 }} : typeof TreeElement

View File

@@ -9,26 +9,26 @@ function C() { this.p = 1; }
>1 : 1
C.prototype = { q: 2 };
>C.prototype = { q: 2 } : { [x: string]: any; q: number; }
>C.prototype : { [x: string]: any; q: number; }
>C.prototype = { q: 2 } : { q: number; }
>C.prototype : { q: number; }
>C : typeof C
>prototype : { [x: string]: any; q: number; }
>{ q: 2 } : { [x: string]: any; q: number; }
>prototype : { q: number; }
>{ q: 2 } : { q: number; }
>q : number
>2 : 2
const c = new C()
>c : C & { [x: string]: any; q: number; }
>new C() : C & { [x: string]: any; q: number; }
>c : C & { q: number; }
>new C() : C & { q: number; }
>C : typeof C
c.p
>c.p : number
>c : C & { [x: string]: any; q: number; }
>c : C & { q: number; }
>p : number
c.q
>c.q : number
>c : C & { [x: string]: any; q: number; }
>c : C & { q: number; }
>q : number

View File

@@ -1,4 +1,4 @@
tests/cases/conformance/salsa/a.js(7,17): error TS2322: Type '{ [x: string]: any; q: number; }' is not assignable to type 'C'.
tests/cases/conformance/salsa/a.js(7,17): error TS2322: Type '{ q: number; }' is not assignable to type 'C'.
Object literal may only specify known properties, and 'q' does not exist in type 'C'.
tests/cases/conformance/salsa/a.js(11,3): error TS2339: Property 'q' does not exist on type 'C'.
@@ -12,7 +12,7 @@ tests/cases/conformance/salsa/a.js(11,3): error TS2339: Property 'q' does not ex
// (Object.defineProperty isn't recognised as a JS special assignment right now.)
C.prototype = { q: 2 };
~~~~
!!! error TS2322: Type '{ [x: string]: any; q: number; }' is not assignable to type 'C'.
!!! error TS2322: Type '{ q: number; }' is not assignable to type 'C'.
!!! error TS2322: Object literal may only specify known properties, and 'q' does not exist in type 'C'.
const c = new C()

View File

@@ -13,11 +13,11 @@ class C { constructor() { this.p = 1; } }
// and that only works on classes with no superclass.
// (Object.defineProperty isn't recognised as a JS special assignment right now.)
C.prototype = { q: 2 };
>C.prototype = { q: 2 } : { [x: string]: any; q: number; }
>C.prototype = { q: 2 } : { q: number; }
>C.prototype : C
>C : typeof C
>prototype : C
>{ q: 2 } : { [x: string]: any; q: number; }
>{ q: 2 } : { q: number; }
>q : number
>2 : 2

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/def.js ===
var Outer = {};
>Outer : typeof Outer
>{} : { [x: string]: any; }
>{} : {}
=== tests/cases/conformance/salsa/a.js ===
Outer.Inner = class {

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/salsa/a.js ===
var obj = {};
>obj : typeof obj
>{} : { [x: string]: any; }
>{} : {}
obj.method = function (hunch) {
>obj.method = function (hunch) { return true;} : (hunch: any) => boolean

View File

@@ -1,20 +1,20 @@
=== tests/cases/conformance/salsa/a.js ===
var my = my || {};
>my : typeof my
>my || {} : typeof my | { [x: string]: any; }
>my || {} : typeof my | {}
>my : typeof my
>{} : { [x: string]: any; }
>{} : {}
my.app = my.app || {};
>my.app = my.app || {} : typeof my.app
>my.app : typeof my.app
>my : typeof my
>app : typeof my.app
>my.app || {} : { [x: string]: any; }
>my.app || {} : {}
>my.app : typeof my.app
>my : typeof my
>app : typeof my.app
>{} : { [x: string]: any; }
>{} : {}
my.app.Application = (function () {
>my.app.Application = (function () {var Application = function () { //...};return Application;})() : () => void
@@ -52,18 +52,18 @@ var min = window.min || {};
>window.min : any
>window : Window
>min : any
>{} : { [x: string]: any; }
>{} : {}
min.app = min.app || {};
>min.app = min.app || {} : typeof min.app
>min.app : typeof min.app
>min : typeof min
>app : typeof min.app
>min.app || {} : { [x: string]: any; }
>min.app || {} : {}
>min.app : typeof min.app
>min : typeof min
>app : typeof min.app
>{} : { [x: string]: any; }
>{} : {}
min.app.Application = (function () {
>min.app.Application = (function () {var Application = function () { //...};return Application;})() : () => void

View File

@@ -1,9 +1,9 @@
=== tests/cases/conformance/salsa/a.js ===
var my = my || {};
>my : typeof my
>my || {} : typeof my | { [x: string]: any; }
>my || {} : typeof my | {}
>my : typeof my
>{} : { [x: string]: any; }
>{} : {}
/** @param {number} n */
my.method = function(n) {
@@ -27,22 +27,22 @@ my.number = 1;
>1 : 1
my.object = {};
>my.object = {} : { [x: string]: any; }
>my.object : { [x: string]: any; }
>my.object = {} : {}
>my.object : {}
>my : typeof my
>object : { [x: string]: any; }
>{} : { [x: string]: any; }
>object : {}
>{} : {}
my.predicate = my.predicate || {};
>my.predicate = my.predicate || {} : typeof my.predicate
>my.predicate : typeof my.predicate
>my : typeof my
>predicate : typeof my.predicate
>my.predicate || {} : { [x: string]: any; }
>my.predicate || {} : {}
>my.predicate : typeof my.predicate
>my : typeof my
>predicate : typeof my.predicate
>{} : { [x: string]: any; }
>{} : {}
my.predicate.query = function () {
>my.predicate.query = function () { var me = this; me.property = false;} : { (): void; another(): number; result: string; }
@@ -149,7 +149,7 @@ var min = window.min || {};
>window.min : any
>window : Window
>min : any
>{} : { [x: string]: any; }
>{} : {}
min.nest = this.min.nest || function () { };
>min.nest = this.min.nest || function () { } : { (): void; other: typeof other; }
@@ -182,15 +182,15 @@ min.nest.other = self.min.nest.other || class { };
>class { } : typeof other
min.property = global.min.property || {};
>min.property = global.min.property || {} : { [x: string]: any; }
>min.property : { [x: string]: any; }
>min.property = global.min.property || {} : {}
>min.property : {}
>min : typeof min
>property : { [x: string]: any; }
>global.min.property || {} : { [x: string]: any; }
>property : {}
>global.min.property || {} : {}
>global.min.property : any
>global.min : any
>global : any
>min : any
>property : any
>{} : { [x: string]: any; }
>{} : {}

View File

@@ -34,13 +34,13 @@ var am;
=== tests/cases/conformance/salsa/roots.js ===
var First = {};
>First : typeof First
>{} : { [x: string]: any; }
>{} : {}
var Common = {};
>Common : typeof Common
>{} : { [x: string]: any; }
>{} : {}
var Workspace = {};
>Workspace : typeof Workspace
>{} : { [x: string]: any; }
>{} : {}

View File

@@ -3,14 +3,14 @@
export const Adapter = {};
>Adapter : typeof Adapter
>{} : { [x: string]: any; }
>{} : {}
Adapter.prop = {};
>Adapter.prop = {} : { [x: string]: any; }
>Adapter.prop : { [x: string]: any; }
>Adapter.prop = {} : {}
>Adapter.prop : {}
>Adapter : typeof Adapter
>prop : { [x: string]: any; }
>{} : { [x: string]: any; }
>prop : {}
>{} : {}
// comment this out, and it works
Adapter.asyncMethod = function() {}

View File

@@ -14,9 +14,7 @@ var bb;
var bbb = new mod.Baz();
>bbb : Symbol(bbb, Decl(use.js, 5, 3))
>mod.Baz : Symbol(Baz)
>mod : Symbol(mod, Decl(use.js, 0, 3))
>Baz : Symbol(Baz)
=== tests/cases/conformance/jsdoc/mod1.js ===
// error

View File

@@ -1,7 +1,7 @@
=== tests/cases/conformance/jsdoc/use.js ===
var mod = require('./mod1.js');
>mod : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>require('./mod1.js') : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>mod : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>require('./mod1.js') : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>require : any
>'./mod1.js' : "./mod1.js"
@@ -17,7 +17,7 @@ var bbb = new mod.Baz();
>bbb : any
>new mod.Baz() : any
>mod.Baz : any
>mod : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>mod : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>Baz : any
=== tests/cases/conformance/jsdoc/mod1.js ===
@@ -31,17 +31,17 @@ class Foo { } // should error
exports.Bar = class { }
>exports.Bar = class { } : typeof Bar
>exports.Bar : typeof Bar
>exports : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>exports : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>Bar : typeof Bar
>class { } : typeof Bar
/** @typedef {number} Baz */
module.exports = {
>module.exports = { Baz: class { }} : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>module.exports : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>module : { "tests/cases/conformance/jsdoc/mod1": { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }; }
>exports : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>{ Baz: class { }} : { [x: string]: any; Baz: typeof Baz; }
>module.exports = { Baz: class { }} : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>module.exports : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>module : { "tests/cases/conformance/jsdoc/mod1": { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }; }
>exports : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>{ Baz: class { }} : { Baz: typeof Baz; }
Baz: class { }
>Baz : typeof Baz
@@ -59,17 +59,17 @@ var Qux = 2;
exports.Quid = 2;
>exports.Quid = 2 : 2
>exports.Quid : any
>exports : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>exports : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>Quid : any
>2 : 2
/** @typedef {number} Quack */
module.exports = {
>module.exports = { Quack: 2} : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>module.exports : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>module : { "tests/cases/conformance/jsdoc/mod1": { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }; }
>exports : { [x: string]: any; Baz: any; Bar: typeof Bar; Quid: any; } | { [x: string]: any; Quack: any; Bar: typeof Bar; Quid: any; }
>{ Quack: 2} : { [x: string]: any; Quack: number; }
>module.exports = { Quack: 2} : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>module.exports : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>module : { "tests/cases/conformance/jsdoc/mod1": { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }; }
>exports : { Baz: any; Bar: typeof Bar; Quid: any; } | { Quack: any; Bar: typeof Bar; Quid: any; }
>{ Quack: 2} : { Quack: number; }
Quack: 2
>Quack : number

View File

@@ -2,7 +2,7 @@
/** @typedef {number} Foo */
const ns = {};
>ns : typeof ns
>{} : { [x: string]: any; }
>{} : {}
ns.Foo = class {}
>ns.Foo = class {} : typeof Foo

View File

@@ -4,11 +4,11 @@ class Bar { }
>Bar : Bar
module.exports = { Foo: Bar };
>module.exports = { Foo: Bar } : { [x: string]: any; Foo: any; }
>module.exports : { [x: string]: any; Foo: any; }
>module : { "tests/cases/conformance/jsdoc/mod3": { [x: string]: any; Foo: any; }; }
>exports : { [x: string]: any; Foo: any; }
>{ Foo: Bar } : { [x: string]: any; Foo: typeof Bar; }
>module.exports = { Foo: Bar } : { Foo: any; }
>module.exports : { Foo: any; }
>module : { "tests/cases/conformance/jsdoc/mod3": { Foo: any; }; }
>exports : { Foo: any; }
>{ Foo: Bar } : { Foo: typeof Bar; }
>Foo : typeof Bar
>Bar : typeof Bar

View File

@@ -1,22 +1,22 @@
=== /a.ts ===
import foo from "foo";
>foo : { [x: string]: any; bar(): number; }
>foo : { bar(): number; }
foo.bar();
>foo.bar() : number
>foo.bar : () => number
>foo : { [x: string]: any; bar(): number; }
>foo : { 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; } } : { [x: string]: any; bar(): number; }
>exports.default : { [x: string]: any; bar(): number; }
>exports.default = { bar() { return 0; } } : { bar(): number; }
>exports.default : { bar(): number; }
>exports : typeof import("/node_modules/foo/index")
>default : { [x: string]: any; bar(): number; }
>{ bar() { return 0; } } : { [x: string]: any; bar(): number; }
>default : { bar(): number; }
>{ bar() { return 0; } } : { bar(): number; }
>bar : () => number
>0 : 0

View File

@@ -0,0 +1,14 @@
// @allowJs: true
// @outDir: ./out
// @filename: file.js
// @ts-check
const obj = {
x: 1,
y: 2
};
/**
* @type {keyof typeof obj}
*/
let selected = "x";
selected = "z"; // should fail

View File

@@ -28,7 +28,7 @@ verify.rangeIs(`
m2(c: C): any {
throw new Error("Method not implemented.");
}
y: { [x: string]: any; };
y: {};
m1(): any {
throw new Error("Method not implemented.");
}