From f6a3a3fc3dc5aac5d5b1bbec8a64656be6cbda85 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 14 Feb 2017 12:04:39 -0800 Subject: [PATCH 01/26] Use '__this__' property in contextual type to indicate type of 'this' --- src/compiler/checker.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2b059e29d09b5..1f59d28cc7cac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11189,6 +11189,19 @@ namespace ts { return getTypeOfSymbol(thisParameter); } } + if (isObjectLiteralMethod(func)) { + // For methods in an object literal, look for a '__this__' property in the contextual + // type for the object literal. If one exists, remove 'undefined' from the type of that + // property and report it as the contextual type for 'this' in the method. + const objectLiteral = func.parent; + const type = getApparentTypeOfContextualType(objectLiteral); + if (type) { + const propertyType = getTypeOfPropertyOfContextualType(type, "___this__"); + if (propertyType) { + return getNonNullableType(propertyType); + } + } + } } return undefined; } From 8cd6c5d8eb27dc12f3fbc17236271440214d2690 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Feb 2017 17:03:39 -0800 Subject: [PATCH 02/26] Introduce ThisType marker interface --- src/compiler/checker.ts | 53 +++++++++++++++++++++++++++++++---------- src/lib/es5.d.ts | 5 ++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1f59d28cc7cac..898b7b4d53909 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -197,6 +197,7 @@ namespace ts { let globalNumberType: ObjectType; let globalBooleanType: ObjectType; let globalRegExpType: ObjectType; + let globalThisType: GenericType; let anyArrayType: Type; let autoArrayType: Type; let anyReadonlyArrayType: Type; @@ -5802,6 +5803,11 @@ namespace ts { return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), arity); } + function getGlobalTypeOrUndefined(name: string, arity = 0): ObjectType { + const symbol = getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined); + return symbol && getTypeOfGlobalSymbol(symbol, arity); + } + /** * Returns a type that is inside a namespace at the global scope, e.g. * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type @@ -11180,6 +11186,22 @@ namespace ts { } } + function getContainingObjectLiteral(func: FunctionLikeDeclaration) { + return func.kind === SyntaxKind.MethodDeclaration && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : + func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? func.parent.parent : + undefined; + } + + function getThisTypeArgument(type: Type): Type { + return getObjectFlags(type) & ObjectFlags.Reference && (type).target === globalThisType ? (type).typeArguments[0] : undefined; + } + + function getThisTypeFromContextualType(type: Type): Type { + return applyToContextualType(type, t => { + return t.flags & TypeFlags.Intersection ? forEach((t).types, getThisTypeArgument) : getThisTypeArgument(t); + }); + } + function getContextualThisParameterType(func: FunctionLikeDeclaration): Type { if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) { const contextualSignature = getContextualSignature(func); @@ -11189,17 +11211,24 @@ namespace ts { return getTypeOfSymbol(thisParameter); } } - if (isObjectLiteralMethod(func)) { - // For methods in an object literal, look for a '__this__' property in the contextual - // type for the object literal. If one exists, remove 'undefined' from the type of that - // property and report it as the contextual type for 'this' in the method. - const objectLiteral = func.parent; - const type = getApparentTypeOfContextualType(objectLiteral); - if (type) { - const propertyType = getTypeOfPropertyOfContextualType(type, "___this__"); - if (propertyType) { - return getNonNullableType(propertyType); + const containingLiteral = getContainingObjectLiteral(func); + if (containingLiteral) { + // We have an object literal method. Check if the containing object literal has a contextual type + // and if that contextual type is or includes a ThisType. If so, T is the contextual type for + // 'this'. We continue looking in any directly enclosing object literals. + let objectLiteral = containingLiteral; + while (true) { + const type = getApparentTypeOfContextualType(objectLiteral); + if (type) { + const thisType = getThisTypeFromContextualType(type); + if (thisType) { + return thisType; + } + } + if (objectLiteral.parent.kind !== SyntaxKind.PropertyAssignment) { + break; } + objectLiteral = objectLiteral.parent.parent; } } } @@ -21175,9 +21204,9 @@ namespace ts { anyArrayType = createArrayType(anyType); autoArrayType = createArrayType(autoType); - const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined); - globalReadonlyArrayType = symbol && getTypeOfGlobalSymbol(symbol, /*arity*/ 1); + globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; + globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1); } function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 038d0344fda72..6ff9b8f533a54 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1384,6 +1384,11 @@ type Record = { [P in K]: T; } +/** + * Marker for contextual 'this' type + */ +interface ThisType { } + /** * Represents a raw buffer of binary data, which is used to store data for the * different typed arrays. ArrayBuffers cannot be read from or written to directly, From 2ca6164fea89ca344b04ee775a472564ae836511 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Feb 2017 17:04:30 -0800 Subject: [PATCH 03/26] Default contextual 'this' type is containing object literal --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 898b7b4d53909..3949a65eea859 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11230,6 +11230,9 @@ namespace ts { } objectLiteral = objectLiteral.parent.parent; } + // There was no contextual ThisType for the containing object literal, so the contextual type + // for 'this' is the type of the object literal itself. + return checkExpressionCached(containingLiteral); } } return undefined; From e512376b0c5ae25d0e66b4c92bc6618cbd262c95 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Feb 2017 17:42:22 -0800 Subject: [PATCH 04/26] Update tests --- tests/cases/compiler/noImplicitThisObjectLiterals.ts | 10 ---------- .../typePredicates/declarationEmitThisPredicates02.ts | 2 +- .../declarationEmitThisPredicatesWithPrivateName02.ts | 2 +- .../expressions/thisKeyword/thisInObjectLiterals.ts | 3 ++- .../conformance/types/thisType/thisTypeInFunctions2.ts | 7 +++---- 5 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 tests/cases/compiler/noImplicitThisObjectLiterals.ts diff --git a/tests/cases/compiler/noImplicitThisObjectLiterals.ts b/tests/cases/compiler/noImplicitThisObjectLiterals.ts deleted file mode 100644 index abd5d9dcfba75..0000000000000 --- a/tests/cases/compiler/noImplicitThisObjectLiterals.ts +++ /dev/null @@ -1,10 +0,0 @@ -// @noImplicitThis: true -let o = { - d: this, // error, this: any - m() { - return this.d.length; // error, this: any - }, - f: function() { - return this.d.length; // error, this: any - } -} diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts index 02f2a798831ec..c17b26f423c85 100644 --- a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicates02.ts @@ -9,7 +9,7 @@ export interface Foo { export const obj = { m(): this is Foo { - let dis = this as Foo; + let dis = this as {} as Foo; return dis.a != null && dis.b != null && dis.c != null; } } \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts index c238bb16ec8a0..94e657db9f399 100644 --- a/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts +++ b/tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName02.ts @@ -9,7 +9,7 @@ interface Foo { export const obj = { m(): this is Foo { - let dis = this as Foo; + let dis = this as {} as Foo; return dis.a != null && dis.b != null && dis.c != null; } } \ No newline at end of file diff --git a/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts b/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts index ddfbb790980e4..6219586b6e590 100644 --- a/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts +++ b/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts @@ -2,9 +2,10 @@ class MyClass { t: number; fn() { + type ContainingThis = this; //type of 'this' in an object literal is the containing scope's this var t = { x: this, y: this.t }; - var t: { x: MyClass; y: number }; + var t: { x: ContainingThis; y: number }; } } diff --git a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts index a574c7a07e951..0d1581633c3e9 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts @@ -32,15 +32,14 @@ extend1({ }); extend2({ init() { - this // this: any because the contextual signature of init doesn't specify this' type + this // this: containing object literal type this.mine - this.willDestroy + //this.willDestroy }, mine: 13, foo() { - this // this: any because of the string indexer + this // this: containing object literal type this.mine - this.willDestroy } }); From d7e153d25228c9c8527dd9d38b464c53729b959d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Feb 2017 17:47:58 -0800 Subject: [PATCH 05/26] Accept new baselines --- tests/baselines/reference/castTest.symbols | 6 ++ tests/baselines/reference/castTest.types | 16 +-- .../commentsOnObjectLiteral2.errors.txt | 5 +- ...declarationEmitThisPredicates02.errors.txt | 2 +- .../declarationEmitThisPredicates02.js | 2 +- ...ThisPredicatesWithPrivateName02.errors.txt | 2 +- ...tionEmitThisPredicatesWithPrivateName02.js | 2 +- .../reference/fatarrowfunctions.symbols | 5 + .../reference/fatarrowfunctions.types | 12 +-- .../fatarrowfunctionsInFunctions.symbols | 5 + .../fatarrowfunctionsInFunctions.types | 16 +-- .../reference/fixSignatureCaching.errors.txt | 98 ++++++++++++++++++- .../looseThisTypeInFunctions.errors.txt | 5 +- .../baselines/reference/objectSpread.symbols | 3 + tests/baselines/reference/objectSpread.types | 12 +-- .../baselines/reference/selfInLambdas.symbols | 7 ++ tests/baselines/reference/selfInLambdas.types | 16 +-- .../baselines/reference/thisBinding2.symbols | 3 + tests/baselines/reference/thisBinding2.types | 8 +- .../reference/thisInObjectLiterals.errors.txt | 9 +- .../reference/thisInObjectLiterals.js | 3 +- .../thisInPropertyBoundDeclarations.symbols | 2 + .../thisInPropertyBoundDeclarations.types | 12 +-- .../reference/thisTypeInFunctions2.js | 14 ++- .../reference/thisTypeInFunctions2.symbols | 29 ++++-- .../reference/thisTypeInFunctions2.types | 49 ++++------ .../thisTypeInObjectLiterals.symbols | 24 +++++ .../reference/thisTypeInObjectLiterals.types | 78 +++++++-------- .../throwInEnclosingStatements.symbols | 1 + .../throwInEnclosingStatements.types | 2 +- .../reference/underscoreTest1.symbols | 6 ++ .../baselines/reference/underscoreTest1.types | 12 +-- 32 files changed, 317 insertions(+), 149 deletions(-) diff --git a/tests/baselines/reference/castTest.symbols b/tests/baselines/reference/castTest.symbols index 944cc8238e6e4..706f75a10287f 100644 --- a/tests/baselines/reference/castTest.symbols +++ b/tests/baselines/reference/castTest.symbols @@ -71,7 +71,13 @@ var p_cast = ({ return new Point(this.x + dx, this.y + dy); >Point : Symbol(Point, Decl(castTest.ts, 11, 37)) +>this.x : Symbol(x, Decl(castTest.ts, 22, 23)) +>this : Symbol(__object, Decl(castTest.ts, 22, 22)) +>x : Symbol(x, Decl(castTest.ts, 22, 23)) >dx : Symbol(dx, Decl(castTest.ts, 25, 18)) +>this.y : Symbol(y, Decl(castTest.ts, 23, 9)) +>this : Symbol(__object, Decl(castTest.ts, 22, 22)) +>y : Symbol(y, Decl(castTest.ts, 23, 9)) >dy : Symbol(dy, Decl(castTest.ts, 25, 21)) }, diff --git a/tests/baselines/reference/castTest.types b/tests/baselines/reference/castTest.types index 666b2ccf78e05..acdc58d0b25f7 100644 --- a/tests/baselines/reference/castTest.types +++ b/tests/baselines/reference/castTest.types @@ -91,15 +91,15 @@ var p_cast = ({ return new Point(this.x + dx, this.y + dy); >new Point(this.x + dx, this.y + dy) : Point >Point : typeof Point ->this.x + dx : any ->this.x : any ->this : any ->x : any +>this.x + dx : number +>this.x : number +>this : { x: number; y: number; add: (dx: number, dy: number) => Point; mult: (p: Point) => Point; } +>x : number >dx : number ->this.y + dy : any ->this.y : any ->this : any ->y : any +>this.y + dy : number +>this.y : number +>this : { x: number; y: number; add: (dx: number, dy: number) => Point; mult: (p: Point) => Point; } +>y : number >dy : number }, diff --git a/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt b/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt index 2a2394ced4860..3748d0387b666 100644 --- a/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt +++ b/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt @@ -1,7 +1,8 @@ tests/cases/compiler/commentsOnObjectLiteral2.ts(1,14): error TS2304: Cannot find name 'makeClass'. +tests/cases/compiler/commentsOnObjectLiteral2.ts(9,17): error TS2339: Property 'name' does not exist on type '{ initialize: (name: any) => void; }'. -==== tests/cases/compiler/commentsOnObjectLiteral2.ts (1 errors) ==== +==== tests/cases/compiler/commentsOnObjectLiteral2.ts (2 errors) ==== var Person = makeClass( ~~~~~~~~~ !!! error TS2304: Cannot find name 'makeClass'. @@ -13,6 +14,8 @@ tests/cases/compiler/commentsOnObjectLiteral2.ts(1,14): error TS2304: Cannot fin */ initialize: function(name) { this.name = name; + ~~~~ +!!! error TS2339: Property 'name' does not exist on type '{ initialize: (name: any) => void; }'. } /* trailing comment 1*/, } ); \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt b/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt index 4d95cf01136fd..e4f95d9880344 100644 --- a/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt +++ b/tests/baselines/reference/declarationEmitThisPredicates02.errors.txt @@ -13,7 +13,7 @@ tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredic m(): this is Foo { ~~~~ !!! error TS2526: A 'this' type is available only in a non-static member of a class or interface. - let dis = this as Foo; + let dis = this as {} as Foo; return dis.a != null && dis.b != null && dis.c != null; } } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitThisPredicates02.js b/tests/baselines/reference/declarationEmitThisPredicates02.js index 0e7c99df1f32c..46deae372ca3f 100644 --- a/tests/baselines/reference/declarationEmitThisPredicates02.js +++ b/tests/baselines/reference/declarationEmitThisPredicates02.js @@ -8,7 +8,7 @@ export interface Foo { export const obj = { m(): this is Foo { - let dis = this as Foo; + let dis = this as {} as Foo; return dis.a != null && dis.b != null && dis.c != null; } } diff --git a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt index 86c0f478133c3..bd2f4700fa248 100644 --- a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt +++ b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.errors.txt @@ -16,7 +16,7 @@ tests/cases/conformance/declarationEmit/typePredicates/declarationEmitThisPredic m(): this is Foo { ~~~~ !!! error TS2526: A 'this' type is available only in a non-static member of a class or interface. - let dis = this as Foo; + let dis = this as {} as Foo; return dis.a != null && dis.b != null && dis.c != null; } } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js index 7ec7ba5dec8a0..fe1a95db5e3fb 100644 --- a/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js +++ b/tests/baselines/reference/declarationEmitThisPredicatesWithPrivateName02.js @@ -8,7 +8,7 @@ interface Foo { export const obj = { m(): this is Foo { - let dis = this as Foo; + let dis = this as {} as Foo; return dis.a != null && dis.b != null && dis.c != null; } } diff --git a/tests/baselines/reference/fatarrowfunctions.symbols b/tests/baselines/reference/fatarrowfunctions.symbols index 6ed865b091459..1e5fb4f317800 100644 --- a/tests/baselines/reference/fatarrowfunctions.symbols +++ b/tests/baselines/reference/fatarrowfunctions.symbols @@ -163,6 +163,11 @@ var messenger = { setTimeout(() => { this.message.toString(); }, 3000); >setTimeout : Symbol(setTimeout, Decl(fatarrowfunctions.ts, 34, 1)) +>this.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) +>this.message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17)) +>this : Symbol(__object, Decl(fatarrowfunctions.ts, 38, 15)) +>message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17)) +>toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) } }; diff --git a/tests/baselines/reference/fatarrowfunctions.types b/tests/baselines/reference/fatarrowfunctions.types index 304c341c91640..1114ae365cbce 100644 --- a/tests/baselines/reference/fatarrowfunctions.types +++ b/tests/baselines/reference/fatarrowfunctions.types @@ -234,12 +234,12 @@ var messenger = { >setTimeout(() => { this.message.toString(); }, 3000) : number >setTimeout : (expression: any, msec?: number, language?: any) => number >() => { this.message.toString(); } : () => void ->this.message.toString() : any ->this.message.toString : any ->this.message : any ->this : any ->message : any ->toString : any +>this.message.toString() : string +>this.message.toString : () => string +>this.message : string +>this : { message: string; start: () => void; } +>message : string +>toString : () => string >3000 : 3000 } }; diff --git a/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols b/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols index 0a86affc21589..f1123f4aa9685 100644 --- a/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols +++ b/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols @@ -16,12 +16,17 @@ var messenger = { var _self = this; >_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11)) +>this : Symbol(__object, Decl(fatarrowfunctionsInFunctions.ts, 2, 15)) setTimeout(function() { >setTimeout : Symbol(setTimeout, Decl(fatarrowfunctionsInFunctions.ts, 0, 0)) _self.message.toString(); +>_self.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) +>_self.message : Symbol(message, Decl(fatarrowfunctionsInFunctions.ts, 2, 17)) >_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11)) +>message : Symbol(message, Decl(fatarrowfunctionsInFunctions.ts, 2, 17)) +>toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) }, 3000); } diff --git a/tests/baselines/reference/fatarrowfunctionsInFunctions.types b/tests/baselines/reference/fatarrowfunctionsInFunctions.types index 8b9bd7ccd7a62..88807f2a37b6b 100644 --- a/tests/baselines/reference/fatarrowfunctionsInFunctions.types +++ b/tests/baselines/reference/fatarrowfunctionsInFunctions.types @@ -18,8 +18,8 @@ var messenger = { >function() { var _self = this; setTimeout(function() { _self.message.toString(); }, 3000); } : () => void var _self = this; ->_self : any ->this : any +>_self : { message: string; start: () => void; } +>this : { message: string; start: () => void; } setTimeout(function() { >setTimeout(function() { _self.message.toString(); }, 3000) : number @@ -27,12 +27,12 @@ var messenger = { >function() { _self.message.toString(); } : () => void _self.message.toString(); ->_self.message.toString() : any ->_self.message.toString : any ->_self.message : any ->_self : any ->message : any ->toString : any +>_self.message.toString() : string +>_self.message.toString : () => string +>_self.message : string +>_self : { message: string; start: () => void; } +>message : string +>toString : () => string }, 3000); >3000 : 3000 diff --git a/tests/baselines/reference/fixSignatureCaching.errors.txt b/tests/baselines/reference/fixSignatureCaching.errors.txt index 7a5c43c966e2d..284a0d1392641 100644 --- a/tests/baselines/reference/fixSignatureCaching.errors.txt +++ b/tests/baselines/reference/fixSignatureCaching.errors.txt @@ -41,19 +41,51 @@ tests/cases/conformance/fixSignatureCaching.ts(639,38): error TS2304: Cannot fin tests/cases/conformance/fixSignatureCaching.ts(640,13): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(641,13): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(704,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(704,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(704,58): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(704,67): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(705,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(734,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(734,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(734,58): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(734,67): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(735,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(783,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(783,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(783,58): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(783,67): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(784,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(804,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(805,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(805,46): error TS2339: Property 'findMatch' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(805,61): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(805,89): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(807,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(827,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(828,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(828,47): error TS2339: Property 'findMatches' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(828,64): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(828,92): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(830,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(844,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(845,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(845,39): error TS2339: Property 'detectOS' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(845,53): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(847,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(869,25): error TS2339: Property 'getVersion' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(869,46): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(890,25): error TS2339: Property 'getVersionStr' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(890,49): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(912,36): error TS2339: Property 'findMatches' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(912,53): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(912,83): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(927,38): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(941,33): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'. +tests/cases/conformance/fixSignatureCaching.ts(941,68): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(951,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. +tests/cases/conformance/fixSignatureCaching.ts(952,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(952,42): error TS2339: Property 'mobileGrade' does not exist on type '{}'. +tests/cases/conformance/fixSignatureCaching.ts(954,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(959,16): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(959,42): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(960,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'. @@ -71,7 +103,7 @@ tests/cases/conformance/fixSignatureCaching.ts(979,23): error TS2304: Cannot fin tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot find name 'window'. -==== tests/cases/conformance/fixSignatureCaching.ts (71 errors) ==== +==== tests/cases/conformance/fixSignatureCaching.ts (103 errors) ==== // Repro from #10697 (function (define, undefined) { @@ -862,7 +894,15 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. return this._cache.mobile; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -894,7 +934,15 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. return this._cache.phone; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -945,7 +993,15 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. return this._cache.tablet; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -966,13 +1022,21 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ userAgent: function () { if (this._cache.userAgent === undefined) { + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua); + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~~ !!! error TS2339: Property 'findMatch' does not exist on type '{}'. ~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } return this._cache.userAgent; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -993,13 +1057,21 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ userAgents: function () { if (this._cache.userAgents === undefined) { + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua); + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~~~~ !!! error TS2339: Property 'findMatches' does not exist on type '{}'. ~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } return this._cache.userAgents; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1014,11 +1086,19 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ os: function () { if (this._cache.os === undefined) { + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.os = impl.detectOS(this.ua); + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~ !!! error TS2339: Property 'detectOS' does not exist on type '{}'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } return this._cache.os; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1043,6 +1123,8 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin return impl.getVersion(key, this.ua); ~~~~~~~~~~ !!! error TS2339: Property 'getVersion' does not exist on type '{}'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1066,6 +1148,8 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin return impl.getVersionStr(key, this.ua); ~~~~~~~~~~~~~ !!! error TS2339: Property 'getVersionStr' does not exist on type '{}'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1092,6 +1176,8 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin !!! error TS2339: Property 'findMatches' does not exist on type '{}'. ~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1107,6 +1193,8 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin pattern = new RegExp(pattern, 'i'); } return pattern.test(this.ua); + ~~ +!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1123,6 +1211,8 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth); ~~~~~~~~~~~~ !!! error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'. + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1133,11 +1223,17 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ mobileGrade: function () { if (this._cache.grade === undefined) { + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.grade = impl.mobileGrade(this); + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~~~~ !!! error TS2339: Property 'mobileGrade' does not exist on type '{}'. } return this._cache.grade; + ~~~~~~ +!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } }; diff --git a/tests/baselines/reference/looseThisTypeInFunctions.errors.txt b/tests/baselines/reference/looseThisTypeInFunctions.errors.txt index bf76c9c964131..7e12a71440685 100644 --- a/tests/baselines/reference/looseThisTypeInFunctions.errors.txt +++ b/tests/baselines/reference/looseThisTypeInFunctions.errors.txt @@ -1,12 +1,13 @@ tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(21,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'. The 'this' types of each signature are incompatible. Type 'void' is not assignable to type 'C'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(25,27): error TS2339: Property 'length' does not exist on type 'number'. tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(33,28): error TS2339: Property 'length' does not exist on type 'number'. tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(37,9): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'I'. tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error TS2339: Property 'length' does not exist on type 'number'. -==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (4 errors) ==== +==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (5 errors) ==== interface I { n: number; explicitThis(this: this, m: number): number; @@ -36,6 +37,8 @@ tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error n: 101, explicitThis: function (m: number) { return m + this.n.length; // error, 'length' does not exist on 'number' + ~~~~~~ +!!! error TS2339: Property 'length' does not exist on type 'number'. }, implicitThis(m: number): number { return m; } }; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 1ec2520e166f2..3487f757aeb75 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -200,6 +200,9 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) >c : Symbol(c, Decl(objectSpread.ts, 45, 3)) >plus : Symbol(plus, Decl(objectSpread.ts, 49, 48)) +>this.p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) +>this : Symbol(__object, Decl(objectSpread.ts, 49, 40)) +>p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) cplus.plus(); >cplus.plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 950dab43465c7..b6ad1d13ae4eb 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -263,13 +263,13 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >cplus : { p: number; plus(): void; } >p : number >plus : () => void ->{ ...c, plus() { return this.p + 1; } } : { plus(): any; p: number; } +>{ ...c, plus() { return this.p + 1; } } : { plus(): number; p: number; } >c : C ->plus : () => any ->this.p + 1 : any ->this.p : any ->this : any ->p : any +>plus : () => number +>this.p + 1 : number +>this.p : number +>this : { plus(): number; p: number; } +>p : number >1 : 1 cplus.plus(); diff --git a/tests/baselines/reference/selfInLambdas.symbols b/tests/baselines/reference/selfInLambdas.symbols index edcc03b6bf683..6f91adefcc15a 100644 --- a/tests/baselines/reference/selfInLambdas.symbols +++ b/tests/baselines/reference/selfInLambdas.symbols @@ -37,8 +37,15 @@ var o = { >onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18)) this.counter++ +>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) +>this : Symbol(__object, Decl(selfInLambdas.ts, 10, 7)) +>counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) + var f = () => this.counter; >f : Symbol(f, Decl(selfInLambdas.ts, 18, 15)) +>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) +>this : Symbol(__object, Decl(selfInLambdas.ts, 10, 7)) +>counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) } diff --git a/tests/baselines/reference/selfInLambdas.types b/tests/baselines/reference/selfInLambdas.types index 614ebc16e6817..a26e1e0bf286d 100644 --- a/tests/baselines/reference/selfInLambdas.types +++ b/tests/baselines/reference/selfInLambdas.types @@ -43,16 +43,16 @@ var o = { this.counter++ >this.counter++ : number ->this.counter : any ->this : any ->counter : any +>this.counter : number +>this : { counter: number; start: () => void; } +>counter : number var f = () => this.counter; ->f : () => any ->() => this.counter : () => any ->this.counter : any ->this : any ->counter : any +>f : () => number +>() => this.counter : () => number +>this.counter : number +>this : { counter: number; start: () => void; } +>counter : number } diff --git a/tests/baselines/reference/thisBinding2.symbols b/tests/baselines/reference/thisBinding2.symbols index cdef9b60b3e7a..507b7e4841956 100644 --- a/tests/baselines/reference/thisBinding2.symbols +++ b/tests/baselines/reference/thisBinding2.symbols @@ -50,6 +50,9 @@ var messenger = { return setTimeout(() => { var x = this.message; }, 3000); >setTimeout : Symbol(setTimeout, Decl(thisBinding2.ts, 12, 1)) >x : Symbol(x, Decl(thisBinding2.ts, 17, 37)) +>this.message : Symbol(message, Decl(thisBinding2.ts, 14, 17)) +>this : Symbol(__object, Decl(thisBinding2.ts, 14, 15)) +>message : Symbol(message, Decl(thisBinding2.ts, 14, 17)) } }; diff --git a/tests/baselines/reference/thisBinding2.types b/tests/baselines/reference/thisBinding2.types index dbd9f83c7412a..4889e6d3b3386 100644 --- a/tests/baselines/reference/thisBinding2.types +++ b/tests/baselines/reference/thisBinding2.types @@ -67,10 +67,10 @@ var messenger = { >setTimeout(() => { var x = this.message; }, 3000) : number >setTimeout : (expression: any, msec?: number, language?: any) => number >() => { var x = this.message; } : () => void ->x : any ->this.message : any ->this : any ->message : any +>x : string +>this.message : string +>this : { message: string; start: () => number; } +>message : string >3000 : 3000 } }; diff --git a/tests/baselines/reference/thisInObjectLiterals.errors.txt b/tests/baselines/reference/thisInObjectLiterals.errors.txt index e89980dc244ef..3da8430802d6a 100644 --- a/tests/baselines/reference/thisInObjectLiterals.errors.txt +++ b/tests/baselines/reference/thisInObjectLiterals.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(7,13): error TS2403: Subsequent variable declarations must have the same type. Variable 't' must be of type '{ x: this; y: number; }', but here has type '{ x: MyClass; y: number; }'. +tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(15,21): error TS2339: Property 'spaaace' does not exist on type '{ f(): any; }'. ==== tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts (1 errors) ==== @@ -6,11 +6,10 @@ tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(7,13): e t: number; fn() { + type ContainingThis = this; //type of 'this' in an object literal is the containing scope's this var t = { x: this, y: this.t }; - var t: { x: MyClass; y: number }; - ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't' must be of type '{ x: this; y: number; }', but here has type '{ x: MyClass; y: number; }'. + var t: { x: ContainingThis; y: number }; } } @@ -18,6 +17,8 @@ tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(7,13): e var obj = { f() { return this.spaaace; + ~~~~~~~ +!!! error TS2339: Property 'spaaace' does not exist on type '{ f(): any; }'. } }; var obj: { f: () => any; }; diff --git a/tests/baselines/reference/thisInObjectLiterals.js b/tests/baselines/reference/thisInObjectLiterals.js index 6c8380060a721..6331f12105d91 100644 --- a/tests/baselines/reference/thisInObjectLiterals.js +++ b/tests/baselines/reference/thisInObjectLiterals.js @@ -3,9 +3,10 @@ class MyClass { t: number; fn() { + type ContainingThis = this; //type of 'this' in an object literal is the containing scope's this var t = { x: this, y: this.t }; - var t: { x: MyClass; y: number }; + var t: { x: ContainingThis; y: number }; } } diff --git a/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols b/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols index 12d3b2db31eb5..6afdd73f77f05 100644 --- a/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols +++ b/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols @@ -70,6 +70,7 @@ class A { a: function() { return this; }, >a : Symbol(a, Decl(thisInPropertyBoundDeclarations.ts, 33, 13)) +>this : Symbol(__object, Decl(thisInPropertyBoundDeclarations.ts, 33, 11)) }; @@ -79,6 +80,7 @@ class A { return { a: function() { return this; }, >a : Symbol(a, Decl(thisInPropertyBoundDeclarations.ts, 38, 16)) +>this : Symbol(__object, Decl(thisInPropertyBoundDeclarations.ts, 38, 14)) }; }; diff --git a/tests/baselines/reference/thisInPropertyBoundDeclarations.types b/tests/baselines/reference/thisInPropertyBoundDeclarations.types index b783c5c1b5fee..7c2b28bfb3e86 100644 --- a/tests/baselines/reference/thisInPropertyBoundDeclarations.types +++ b/tests/baselines/reference/thisInPropertyBoundDeclarations.types @@ -84,9 +84,9 @@ class A { >{ a: function() { return this; }, } : { a: () => any; } a: function() { return this; }, ->a : () => any ->function() { return this; } : () => any ->this : any +>a : () => { a: any; } +>function() { return this; } : () => { a: any; } +>this : { a: () => any; } }; @@ -98,9 +98,9 @@ class A { >{ a: function() { return this; }, } : { a: () => any; } a: function() { return this; }, ->a : () => any ->function() { return this; } : () => any ->this : any +>a : () => { a: any; } +>function() { return this; } : () => { a: any; } +>this : { a: () => any; } }; }; diff --git a/tests/baselines/reference/thisTypeInFunctions2.js b/tests/baselines/reference/thisTypeInFunctions2.js index f52438a19ab5e..45b26fe84d845 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.js +++ b/tests/baselines/reference/thisTypeInFunctions2.js @@ -33,15 +33,14 @@ extend1({ }); extend2({ init() { - this // this: any because the contextual signature of init doesn't specify this' type + this // this: containing object literal type this.mine - this.willDestroy + //this.willDestroy }, mine: 13, foo() { - this // this: any because of the string indexer + this // this: containing object literal type this.mine - this.willDestroy } }); @@ -70,15 +69,14 @@ extend1({ }); extend2({ init: function () { - this; // this: any because the contextual signature of init doesn't specify this' type + this; // this: containing object literal type this.mine; - this.willDestroy; + //this.willDestroy }, mine: 13, foo: function () { - this; // this: any because of the string indexer + this; // this: containing object literal type this.mine; - this.willDestroy; } }); simple({ diff --git a/tests/baselines/reference/thisTypeInFunctions2.symbols b/tests/baselines/reference/thisTypeInFunctions2.symbols index 5cc26e3ad43a3..d9d0be723b61a 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.symbols +++ b/tests/baselines/reference/thisTypeInFunctions2.symbols @@ -89,9 +89,15 @@ extend2({ init() { >init : Symbol(init, Decl(thisTypeInFunctions2.ts, 32, 9)) - this // this: any because the contextual signature of init doesn't specify this' type + this // this: containing object literal type +>this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) + this.mine - this.willDestroy +>this.mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) +>this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) +>mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) + + //this.willDestroy }, mine: 13, >mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) @@ -99,9 +105,13 @@ extend2({ foo() { >foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 38, 13)) - this // this: any because of the string indexer + this // this: containing object literal type +>this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) + this.mine - this.willDestroy +>this.mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) +>this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) +>mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) } }); @@ -109,17 +119,20 @@ simple({ >simple : Symbol(simple, Decl(thisTypeInFunctions2.ts, 17, 57)) foo(n) { ->foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 46, 8)) ->n : Symbol(n, Decl(thisTypeInFunctions2.ts, 47, 8)) +>foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 45, 8)) +>n : Symbol(n, Decl(thisTypeInFunctions2.ts, 46, 8)) return n.length + this.bar(); >n.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->n : Symbol(n, Decl(thisTypeInFunctions2.ts, 47, 8)) +>n : Symbol(n, Decl(thisTypeInFunctions2.ts, 46, 8)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>this.bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 48, 6)) +>this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 45, 7)) +>bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 48, 6)) }, bar() { ->bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 49, 6)) +>bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 48, 6)) return 14; } diff --git a/tests/baselines/reference/thisTypeInFunctions2.types b/tests/baselines/reference/thisTypeInFunctions2.types index 3cf6c1d2faedf..f79426529eaa5 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.types +++ b/tests/baselines/reference/thisTypeInFunctions2.types @@ -92,26 +92,22 @@ extend1({ } }); extend2({ ->extend2({ init() { this // this: any because the contextual signature of init doesn't specify this' type this.mine this.willDestroy }, mine: 13, foo() { this // this: any because of the string indexer this.mine this.willDestroy }}) : void +>extend2({ init() { this // this: containing object literal type this.mine //this.willDestroy }, mine: 13, foo() { this // this: containing object literal type this.mine }}) : void >extend2 : (args: IndexedWithoutThis) => void ->{ init() { this // this: any because the contextual signature of init doesn't specify this' type this.mine this.willDestroy }, mine: 13, foo() { this // this: any because of the string indexer this.mine this.willDestroy }} : { init(): void; mine: number; foo(): void; } +>{ init() { this // this: containing object literal type this.mine //this.willDestroy }, mine: 13, foo() { this // this: containing object literal type this.mine }} : { init(): void; mine: number; foo(): void; } init() { >init : () => void - this // this: any because the contextual signature of init doesn't specify this' type ->this : any + this // this: containing object literal type +>this : { init(): void; mine: number; foo(): void; } this.mine ->this.mine : any ->this : any ->mine : any - - this.willDestroy ->this.willDestroy : any ->this : any ->willDestroy : any +>this.mine : number +>this : { init(): void; mine: number; foo(): void; } +>mine : number + //this.willDestroy }, mine: 13, >mine : number @@ -120,39 +116,34 @@ extend2({ foo() { >foo : () => void - this // this: any because of the string indexer ->this : any + this // this: containing object literal type +>this : { init(): void; mine: number; foo(): void; } this.mine ->this.mine : any ->this : any ->mine : any - - this.willDestroy ->this.willDestroy : any ->this : any ->willDestroy : any +>this.mine : number +>this : { init(): void; mine: number; foo(): void; } +>mine : number } }); simple({ >simple({ foo(n) { return n.length + this.bar(); }, bar() { return 14; }}) : void >simple : (arg: SimpleInterface) => void ->{ foo(n) { return n.length + this.bar(); }, bar() { return 14; }} : { foo(n: string): any; bar(): number; } +>{ foo(n) { return n.length + this.bar(); }, bar() { return 14; }} : { foo(n: string): number; bar(): number; } foo(n) { ->foo : (n: string) => any +>foo : (n: string) => number >n : string return n.length + this.bar(); ->n.length + this.bar() : any +>n.length + this.bar() : number >n.length : number >n : string >length : number ->this.bar() : any ->this.bar : any ->this : any ->bar : any +>this.bar() : number +>this.bar : () => number +>this : { foo(n: string): number; bar(): number; } +>bar : () => number }, bar() { diff --git a/tests/baselines/reference/thisTypeInObjectLiterals.symbols b/tests/baselines/reference/thisTypeInObjectLiterals.symbols index af4badf1c0fe4..ad786a4a247f5 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals.symbols +++ b/tests/baselines/reference/thisTypeInObjectLiterals.symbols @@ -9,11 +9,22 @@ let o = { >m : Symbol(m, Decl(thisTypeInObjectLiterals.ts, 1, 13)) return this.d.length; +>this.d.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 0, 7)) +>d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + }, f: function() { >f : Symbol(f, Decl(thisTypeInObjectLiterals.ts, 4, 6)) return this.d.length; +>this.d.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 0, 7)) +>d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) } } @@ -27,12 +38,22 @@ let mutuallyRecursive = { >start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 11, 11)) return this.passthrough(this.a); +>this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) +>this.a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) + }, passthrough(n: number) { >passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) >n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 15, 16)) return this.sub1(n); +>this.sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) >n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 15, 16)) }, @@ -44,6 +65,9 @@ let mutuallyRecursive = { >n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) return this.passthrough(n - 1); +>this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) >n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) } return n; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals.types b/tests/baselines/reference/thisTypeInObjectLiterals.types index 240cfaa54f975..d5c6d851faf15 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals.types @@ -1,66 +1,66 @@ === tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts === let o = { ->o : { d: string; m(): any; f: () => any; } ->{ d: "bar", m() { return this.d.length; }, f: function() { return this.d.length; }} : { d: string; m(): any; f: () => any; } +>o : { d: string; m(): number; f: () => number; } +>{ d: "bar", m() { return this.d.length; }, f: function() { return this.d.length; }} : { d: string; m(): number; f: () => number; } d: "bar", >d : string >"bar" : "bar" m() { ->m : () => any +>m : () => number return this.d.length; ->this.d.length : any ->this.d : any ->this : any ->d : any ->length : any +>this.d.length : number +>this.d : string +>this : { d: string; m(): number; f: () => number; } +>d : string +>length : number }, f: function() { ->f : () => any ->function() { return this.d.length; } : () => any +>f : () => number +>function() { return this.d.length; } : () => number return this.d.length; ->this.d.length : any ->this.d : any ->this : any ->d : any ->length : any +>this.d.length : number +>this.d : string +>this : { d: string; m(): number; f: () => number; } +>d : string +>length : number } } let mutuallyRecursive = { ->mutuallyRecursive : { a: number; start(): any; passthrough(n: number): any; sub1(n: number): number; } ->{ a: 100, start() { return this.passthrough(this.a); }, passthrough(n: number) { return this.sub1(n); }, sub1(n: number): number { if (n > 0) { return this.passthrough(n - 1); } return n; }} : { a: number; start(): any; passthrough(n: number): any; sub1(n: number): number; } +>mutuallyRecursive : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } +>{ a: 100, start() { return this.passthrough(this.a); }, passthrough(n: number) { return this.sub1(n); }, sub1(n: number): number { if (n > 0) { return this.passthrough(n - 1); } return n; }} : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } a: 100, >a : number >100 : 100 start() { ->start : () => any +>start : () => number return this.passthrough(this.a); ->this.passthrough(this.a) : any ->this.passthrough : any ->this : any ->passthrough : any ->this.a : any ->this : any ->a : any +>this.passthrough(this.a) : number +>this.passthrough : (n: number) => number +>this : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } +>passthrough : (n: number) => number +>this.a : number +>this : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } +>a : number }, passthrough(n: number) { ->passthrough : (n: number) => any +>passthrough : (n: number) => number >n : number return this.sub1(n); ->this.sub1(n) : any ->this.sub1 : any ->this : any ->sub1 : any +>this.sub1(n) : number +>this.sub1 : (n: number) => number +>this : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } +>sub1 : (n: number) => number >n : number }, @@ -74,10 +74,10 @@ let mutuallyRecursive = { >0 : 0 return this.passthrough(n - 1); ->this.passthrough(n - 1) : any ->this.passthrough : any ->this : any ->passthrough : any +>this.passthrough(n - 1) : number +>this.passthrough : (n: number) => number +>this : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } +>passthrough : (n: number) => number >n - 1 : number >n : number >1 : 1 @@ -88,10 +88,10 @@ let mutuallyRecursive = { } var i: number = mutuallyRecursive.start(); >i : number ->mutuallyRecursive.start() : any ->mutuallyRecursive.start : () => any ->mutuallyRecursive : { a: number; start(): any; passthrough(n: number): any; sub1(n: number): number; } ->start : () => any +>mutuallyRecursive.start() : number +>mutuallyRecursive.start : () => number +>mutuallyRecursive : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } +>start : () => number interface I { >I : I @@ -113,5 +113,5 @@ interface I { var impl: I = mutuallyRecursive; >impl : I >I : I ->mutuallyRecursive : { a: number; start(): any; passthrough(n: number): any; sub1(n: number): number; } +>mutuallyRecursive : { a: number; start(): number; passthrough(n: number): number; sub1(n: number): number; } diff --git a/tests/baselines/reference/throwInEnclosingStatements.symbols b/tests/baselines/reference/throwInEnclosingStatements.symbols index 63ed9dde5784a..94f7baee021a7 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.symbols +++ b/tests/baselines/reference/throwInEnclosingStatements.symbols @@ -89,6 +89,7 @@ var aa = { >biz : Symbol(biz, Decl(throwInEnclosingStatements.ts, 41, 10)) throw this; +>this : Symbol(__object, Decl(throwInEnclosingStatements.ts, 40, 8)) } } diff --git a/tests/baselines/reference/throwInEnclosingStatements.types b/tests/baselines/reference/throwInEnclosingStatements.types index 2d99ac435aebf..d859bbd639237 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.types +++ b/tests/baselines/reference/throwInEnclosingStatements.types @@ -104,7 +104,7 @@ var aa = { >biz : () => void throw this; ->this : any +>this : { id: number; biz(): void; } } } diff --git a/tests/baselines/reference/underscoreTest1.symbols b/tests/baselines/reference/underscoreTest1.symbols index 89815bd2371a6..018633344ebd2 100644 --- a/tests/baselines/reference/underscoreTest1.symbols +++ b/tests/baselines/reference/underscoreTest1.symbols @@ -395,10 +395,16 @@ var buttonView = { onClick: function () { alert('clicked: ' + this.label); }, >onClick : Symbol(onClick, Decl(underscoreTest1_underscoreTests.ts, 97, 24)) >alert : Symbol(alert, Decl(underscoreTest1_underscoreTests.ts, 2, 14)) +>this.label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) +>this : Symbol(__object, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) +>label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) onHover: function () { alert('hovering: ' + this.label); } >onHover : Symbol(onHover, Decl(underscoreTest1_underscoreTests.ts, 98, 62)) >alert : Symbol(alert, Decl(underscoreTest1_underscoreTests.ts, 2, 14)) +>this.label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) +>this : Symbol(__object, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) +>label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) }; _.bindAll(buttonView); diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 97e064fb12c45..0af9b55d25a04 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -827,9 +827,9 @@ var buttonView = { >alert : (x: string) => void >'clicked: ' + this.label : string >'clicked: ' : "clicked: " ->this.label : any ->this : any ->label : any +>this.label : string +>this : { label: string; onClick: () => void; onHover: () => void; } +>label : string onHover: function () { alert('hovering: ' + this.label); } >onHover : () => void @@ -838,9 +838,9 @@ var buttonView = { >alert : (x: string) => void >'hovering: ' + this.label : string >'hovering: ' : "hovering: " ->this.label : any ->this : any ->label : any +>this.label : string +>this : { label: string; onClick: () => void; onHover: () => void; } +>label : string }; _.bindAll(buttonView); From 27346b13d039a694ff815db81ba6f6df5667fe2e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Feb 2017 20:22:46 -0800 Subject: [PATCH 06/26] Accept new baselines --- tests/baselines/reference/fatarrowfunctions.symbols | 2 +- .../reference/fatarrowfunctionsInFunctions.symbols | 2 +- tests/baselines/reference/objectSpread.symbols | 2 +- tests/baselines/reference/selfInLambdas.symbols | 4 ++-- tests/baselines/reference/thisBinding2.symbols | 2 +- .../reference/thisTypeInObjectLiterals.symbols | 12 ++++++------ .../reference/throwInEnclosingStatements.symbols | 2 +- tests/baselines/reference/underscoreTest1.symbols | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/baselines/reference/fatarrowfunctions.symbols b/tests/baselines/reference/fatarrowfunctions.symbols index 1e5fb4f317800..25213a9bbf8c9 100644 --- a/tests/baselines/reference/fatarrowfunctions.symbols +++ b/tests/baselines/reference/fatarrowfunctions.symbols @@ -165,7 +165,7 @@ var messenger = { >setTimeout : Symbol(setTimeout, Decl(fatarrowfunctions.ts, 34, 1)) >this.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) >this.message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17)) ->this : Symbol(__object, Decl(fatarrowfunctions.ts, 38, 15)) +>this : Symbol(messenger, Decl(fatarrowfunctions.ts, 38, 15)) >message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17)) >toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) } diff --git a/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols b/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols index f1123f4aa9685..977dd39460dfc 100644 --- a/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols +++ b/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols @@ -16,7 +16,7 @@ var messenger = { var _self = this; >_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11)) ->this : Symbol(__object, Decl(fatarrowfunctionsInFunctions.ts, 2, 15)) +>this : Symbol(messenger, Decl(fatarrowfunctionsInFunctions.ts, 2, 15)) setTimeout(function() { >setTimeout : Symbol(setTimeout, Decl(fatarrowfunctionsInFunctions.ts, 0, 0)) diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 3487f757aeb75..a734066d5e714 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -201,7 +201,7 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >c : Symbol(c, Decl(objectSpread.ts, 45, 3)) >plus : Symbol(plus, Decl(objectSpread.ts, 49, 48)) >this.p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) ->this : Symbol(__object, Decl(objectSpread.ts, 49, 40)) +>this : Symbol(cplus, Decl(objectSpread.ts, 49, 40)) >p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) cplus.plus(); diff --git a/tests/baselines/reference/selfInLambdas.symbols b/tests/baselines/reference/selfInLambdas.symbols index 6f91adefcc15a..0a51113710ba9 100644 --- a/tests/baselines/reference/selfInLambdas.symbols +++ b/tests/baselines/reference/selfInLambdas.symbols @@ -38,13 +38,13 @@ var o = { this.counter++ >this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) ->this : Symbol(__object, Decl(selfInLambdas.ts, 10, 7)) +>this : Symbol(o, Decl(selfInLambdas.ts, 10, 7)) >counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) var f = () => this.counter; >f : Symbol(f, Decl(selfInLambdas.ts, 18, 15)) >this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) ->this : Symbol(__object, Decl(selfInLambdas.ts, 10, 7)) +>this : Symbol(o, Decl(selfInLambdas.ts, 10, 7)) >counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) } diff --git a/tests/baselines/reference/thisBinding2.symbols b/tests/baselines/reference/thisBinding2.symbols index 507b7e4841956..f8436f5248bf1 100644 --- a/tests/baselines/reference/thisBinding2.symbols +++ b/tests/baselines/reference/thisBinding2.symbols @@ -51,7 +51,7 @@ var messenger = { >setTimeout : Symbol(setTimeout, Decl(thisBinding2.ts, 12, 1)) >x : Symbol(x, Decl(thisBinding2.ts, 17, 37)) >this.message : Symbol(message, Decl(thisBinding2.ts, 14, 17)) ->this : Symbol(__object, Decl(thisBinding2.ts, 14, 15)) +>this : Symbol(messenger, Decl(thisBinding2.ts, 14, 15)) >message : Symbol(message, Decl(thisBinding2.ts, 14, 17)) } }; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals.symbols b/tests/baselines/reference/thisTypeInObjectLiterals.symbols index ad786a4a247f5..fd6d6ecebd5c8 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals.symbols +++ b/tests/baselines/reference/thisTypeInObjectLiterals.symbols @@ -11,7 +11,7 @@ let o = { return this.d.length; >this.d.length : Symbol(String.length, Decl(lib.d.ts, --, --)) >this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) ->this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 0, 7)) +>this : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 0, 7)) >d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) @@ -22,7 +22,7 @@ let o = { return this.d.length; >this.d.length : Symbol(String.length, Decl(lib.d.ts, --, --)) >this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) ->this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 0, 7)) +>this : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 0, 7)) >d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) } @@ -39,10 +39,10 @@ let mutuallyRecursive = { return this.passthrough(this.a); >this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) >passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) >this.a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) ->this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) >a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) }, @@ -52,7 +52,7 @@ let mutuallyRecursive = { return this.sub1(n); >this.sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) ->this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) >sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) >n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 15, 16)) @@ -66,7 +66,7 @@ let mutuallyRecursive = { return this.passthrough(n - 1); >this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->this : Symbol(__object, Decl(thisTypeInObjectLiterals.ts, 10, 23)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) >passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) >n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) } diff --git a/tests/baselines/reference/throwInEnclosingStatements.symbols b/tests/baselines/reference/throwInEnclosingStatements.symbols index 94f7baee021a7..36dcd3cfcbdb5 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.symbols +++ b/tests/baselines/reference/throwInEnclosingStatements.symbols @@ -89,7 +89,7 @@ var aa = { >biz : Symbol(biz, Decl(throwInEnclosingStatements.ts, 41, 10)) throw this; ->this : Symbol(__object, Decl(throwInEnclosingStatements.ts, 40, 8)) +>this : Symbol(aa, Decl(throwInEnclosingStatements.ts, 40, 8)) } } diff --git a/tests/baselines/reference/underscoreTest1.symbols b/tests/baselines/reference/underscoreTest1.symbols index 459674cdbe89c..3b578be8165fe 100644 --- a/tests/baselines/reference/underscoreTest1.symbols +++ b/tests/baselines/reference/underscoreTest1.symbols @@ -396,14 +396,14 @@ var buttonView = { >onClick : Symbol(onClick, Decl(underscoreTest1_underscoreTests.ts, 97, 24)) >alert : Symbol(alert, Decl(underscoreTest1_underscoreTests.ts, 2, 14)) >this.label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) ->this : Symbol(__object, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) +>this : Symbol(buttonView, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) >label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) onHover: function () { alert('hovering: ' + this.label); } >onHover : Symbol(onHover, Decl(underscoreTest1_underscoreTests.ts, 98, 62)) >alert : Symbol(alert, Decl(underscoreTest1_underscoreTests.ts, 2, 14)) >this.label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) ->this : Symbol(__object, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) +>this : Symbol(buttonView, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) >label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) }; From e3a0687327128c4cce55b8ce448ce8ad7d3fca9b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 17 Feb 2017 06:56:58 -0800 Subject: [PATCH 07/26] Contextual this in 'obj.xxx = function(...)' or 'obj[xxx] = function(...)' --- src/compiler/checker.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3208d303ab0dc..9fb71884c51ad 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11518,6 +11518,14 @@ namespace ts { // for 'this' is the type of the object literal itself. return checkExpressionCached(containingLiteral); } + // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the + // contextual type for 'this' is 'obj'. + if (func.parent.kind === SyntaxKind.BinaryExpression && (func.parent).operatorToken.kind === SyntaxKind.EqualsToken) { + const target = (func.parent).left; + if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) { + return checkExpressionCached((target).expression); + } + } } return undefined; } From 168d367b5e740ae1896c01a26d6bb3d2af038566 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 22 Feb 2017 19:16:55 -0800 Subject: [PATCH 08/26] Contextually type 'this' in accessors of object literals --- src/compiler/checker.ts | 97 +++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9fb71884c51ad..69c294e97c2d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8983,11 +8983,19 @@ namespace ts { return regularNew; } + function getWidenedProperty(prop: Symbol): Symbol { + const original = getTypeOfSymbol(prop); + const widened = getWidenedType(original); + return widened === original ? prop : createSymbolWithType(prop, widened); + } + function getWidenedTypeOfObjectLiteral(type: Type): Type { - const members = transformTypeOfMembers(type, prop => { - const widened = getWidenedType(prop); - return prop === widened ? prop : widened; - }); + const members = createMap(); + for (let prop of getPropertiesOfObjectType(type)) { + // Since get accessors already widen their return value there is no need to + // widen accessor based properties here. + members.set(prop.name, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop) : prop); + }; const stringIndexInfo = getIndexInfoOfType(type, IndexKind.String); const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number); return createAnonymousType(type.symbol, members, emptyArray, emptyArray, @@ -11471,7 +11479,9 @@ namespace ts { } function getContainingObjectLiteral(func: FunctionLikeDeclaration) { - return func.kind === SyntaxKind.MethodDeclaration && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : + return (func.kind === SyntaxKind.MethodDeclaration || + func.kind === SyntaxKind.GetAccessor || + func.kind === SyntaxKind.SetAccessor) && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? func.parent : func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? func.parent.parent : undefined; } @@ -11487,7 +11497,10 @@ namespace ts { } function getContextualThisParameterType(func: FunctionLikeDeclaration): Type { - if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) { + if (func.kind === SyntaxKind.ArrowFunction) { + return undefined; + } + if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { const contextualSignature = getContextualSignature(func); if (contextualSignature) { const thisParameter = contextualSignature.thisParameter; @@ -11495,36 +11508,36 @@ namespace ts { return getTypeOfSymbol(thisParameter); } } - const containingLiteral = getContainingObjectLiteral(func); - if (containingLiteral) { - // We have an object literal method. Check if the containing object literal has a contextual type - // and if that contextual type is or includes a ThisType. If so, T is the contextual type for - // 'this'. We continue looking in any directly enclosing object literals. - let objectLiteral = containingLiteral; - while (true) { - const type = getApparentTypeOfContextualType(objectLiteral); - if (type) { - const thisType = getThisTypeFromContextualType(type); - if (thisType) { - return thisType; - } - } - if (objectLiteral.parent.kind !== SyntaxKind.PropertyAssignment) { - break; + } + const containingLiteral = getContainingObjectLiteral(func); + if (containingLiteral) { + // We have an object literal method. Check if the containing object literal has a contextual type + // and if that contextual type is or includes a ThisType. If so, T is the contextual type for + // 'this'. We continue looking in any directly enclosing object literals. + let objectLiteral = containingLiteral; + while (true) { + const type = getApparentTypeOfContextualType(objectLiteral); + if (type) { + const thisType = getThisTypeFromContextualType(type); + if (thisType) { + return thisType; } - objectLiteral = objectLiteral.parent.parent; } - // There was no contextual ThisType for the containing object literal, so the contextual type - // for 'this' is the type of the object literal itself. - return checkExpressionCached(containingLiteral); - } - // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the - // contextual type for 'this' is 'obj'. - if (func.parent.kind === SyntaxKind.BinaryExpression && (func.parent).operatorToken.kind === SyntaxKind.EqualsToken) { - const target = (func.parent).left; - if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) { - return checkExpressionCached((target).expression); + if (objectLiteral.parent.kind !== SyntaxKind.PropertyAssignment) { + break; } + objectLiteral = objectLiteral.parent.parent; + } + // There was no contextual ThisType for the containing object literal, so the contextual type + // for 'this' is the type of the object literal itself. + return checkExpressionCached(containingLiteral); + } + // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the + // contextual type for 'this' is 'obj'. + if (func.parent.kind === SyntaxKind.BinaryExpression && (func.parent).operatorToken.kind === SyntaxKind.EqualsToken) { + const target = (func.parent).left; + if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) { + return checkExpressionCached((target).expression); } } return undefined; @@ -12287,7 +12300,7 @@ namespace ts { // A set accessor declaration is processed in the same manner // as an ordinary function declaration with a single parameter and a Void return type. Debug.assert(memberDecl.kind === SyntaxKind.GetAccessor || memberDecl.kind === SyntaxKind.SetAccessor); - checkAccessorDeclaration(memberDecl); + checkNodeDeferred(memberDecl); } if (hasDynamicName(memberDecl)) { @@ -16942,13 +16955,8 @@ namespace ts { checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); } } - if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) { - checkSourceElement(node.body); - registerForUnusedIdentifiersCheck(node); - } - else { - checkNodeDeferred(node); - } + checkSourceElement(node.body); + registerForUnusedIdentifiersCheck(node); } function checkAccessorDeclarationTypesIdentical(first: AccessorDeclaration, second: AccessorDeclaration, getAnnotatedType: (a: AccessorDeclaration) => Type, message: DiagnosticMessage) { @@ -16959,11 +16967,6 @@ namespace ts { } } - function checkAccessorDeferred(node: AccessorDeclaration) { - checkSourceElement(node.body); - registerForUnusedIdentifiersCheck(node); - } - function checkMissingDeclaration(node: Node) { checkDecorators(node); } @@ -20630,7 +20633,7 @@ namespace ts { break; case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: - checkAccessorDeferred(node); + checkAccessorDeclaration(node); break; case SyntaxKind.ClassExpression: checkClassExpressionDeferred(node); From c2d8a593b9eb9642d7a2bc57d4cd49bdd85c206e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 22 Feb 2017 19:18:53 -0800 Subject: [PATCH 09/26] Accept new baselines --- .../commentsOnObjectLiteral3.symbols | 7 +++++ .../reference/commentsOnObjectLiteral3.types | 26 +++++++++---------- ...declFileObjectLiteralWithAccessors.symbols | 3 +++ .../declFileObjectLiteralWithAccessors.types | 6 ++--- ...eclFileObjectLiteralWithOnlySetter.symbols | 3 +++ .../declFileObjectLiteralWithOnlySetter.types | 6 ++--- ...iationAssignmentWithIndexingOnLHS3.symbols | 7 +++++ ...ntiationAssignmentWithIndexingOnLHS3.types | 12 ++++----- .../thisTypeInAccessorsNegative.errors.txt | 5 +--- 9 files changed, 46 insertions(+), 29 deletions(-) diff --git a/tests/baselines/reference/commentsOnObjectLiteral3.symbols b/tests/baselines/reference/commentsOnObjectLiteral3.symbols index 3d58fe2d6d7eb..34b4c706b42ae 100644 --- a/tests/baselines/reference/commentsOnObjectLiteral3.symbols +++ b/tests/baselines/reference/commentsOnObjectLiteral3.symbols @@ -21,6 +21,10 @@ var v = { >a : Symbol(a, Decl(commentsOnObjectLiteral3.ts, 8, 13), Decl(commentsOnObjectLiteral3.ts, 12, 18)) return this.prop; +>this.prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) +>this : Symbol(v, Decl(commentsOnObjectLiteral3.ts, 1, 7)) +>prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) + } /*trailing 1*/, //setter set a(value) { @@ -28,6 +32,9 @@ var v = { >value : Symbol(value, Decl(commentsOnObjectLiteral3.ts, 14, 7)) this.prop = value; +>this.prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) +>this : Symbol(v, Decl(commentsOnObjectLiteral3.ts, 1, 7)) +>prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) >value : Symbol(value, Decl(commentsOnObjectLiteral3.ts, 14, 7)) } // trailing 2 diff --git a/tests/baselines/reference/commentsOnObjectLiteral3.types b/tests/baselines/reference/commentsOnObjectLiteral3.types index 4053e7e3f8938..b869e96140158 100644 --- a/tests/baselines/reference/commentsOnObjectLiteral3.types +++ b/tests/baselines/reference/commentsOnObjectLiteral3.types @@ -1,8 +1,8 @@ === tests/cases/compiler/commentsOnObjectLiteral3.ts === var v = { ->v : { prop: number; func: () => void; func1(): void; a: any; } ->{ //property prop: 1 /* multiple trailing comments */ /*trailing comments*/, //property func: function () { }, //PropertyName + CallSignature func1() { }, //getter get a() { return this.prop; } /*trailing 1*/, //setter set a(value) { this.prop = value; } // trailing 2} : { prop: number; func: () => void; func1(): void; a: any; } +>v : { prop: number; func: () => void; func1(): void; a: number; } +>{ //property prop: 1 /* multiple trailing comments */ /*trailing comments*/, //property func: function () { }, //PropertyName + CallSignature func1() { }, //getter get a() { return this.prop; } /*trailing 1*/, //setter set a(value) { this.prop = value; } // trailing 2} : { prop: number; func: () => void; func1(): void; a: number; } //property prop: 1 /* multiple trailing comments */ /*trailing comments*/, @@ -21,25 +21,25 @@ var v = { //getter get a() { ->a : any +>a : number return this.prop; ->this.prop : any ->this : any ->prop : any +>this.prop : number +>this : { prop: number; func: () => void; func1(): void; a: number; } +>prop : number } /*trailing 1*/, //setter set a(value) { ->a : any ->value : any +>a : number +>value : number this.prop = value; ->this.prop = value : any ->this.prop : any ->this : any ->prop : any ->value : any +>this.prop = value : number +>this.prop : number +>this : { prop: number; func: () => void; func1(): void; a: number; } +>prop : number +>value : number } // trailing 2 }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols b/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols index 862b0b3781eff..df94b262c74cb 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols @@ -15,6 +15,9 @@ function /*1*/makePoint(x: number) { set x(a: number) { this.b = a; } >x : Symbol(x, Decl(declFileObjectLiteralWithAccessors.ts, 3, 14), Decl(declFileObjectLiteralWithAccessors.ts, 4, 30)) >a : Symbol(a, Decl(declFileObjectLiteralWithAccessors.ts, 5, 14)) +>this.b : Symbol(b, Decl(declFileObjectLiteralWithAccessors.ts, 2, 12)) +>this : Symbol(__object, Decl(declFileObjectLiteralWithAccessors.ts, 2, 10)) +>b : Symbol(b, Decl(declFileObjectLiteralWithAccessors.ts, 2, 12)) >a : Symbol(a, Decl(declFileObjectLiteralWithAccessors.ts, 5, 14)) }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.types b/tests/baselines/reference/declFileObjectLiteralWithAccessors.types index 389b88de565c7..1c36f3211189c 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.types +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.types @@ -19,9 +19,9 @@ function /*1*/makePoint(x: number) { >x : number >a : number >this.b = a : number ->this.b : any ->this : any ->b : any +>this.b : number +>this : { b: number; x: number; } +>b : number >a : number }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols index f747446614018..9dd2461b871fa 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols @@ -11,6 +11,9 @@ function /*1*/makePoint(x: number) { set x(a: number) { this.b = a; } >x : Symbol(x, Decl(declFileObjectLiteralWithOnlySetter.ts, 3, 14)) >a : Symbol(a, Decl(declFileObjectLiteralWithOnlySetter.ts, 4, 14)) +>this.b : Symbol(b, Decl(declFileObjectLiteralWithOnlySetter.ts, 2, 12)) +>this : Symbol(__object, Decl(declFileObjectLiteralWithOnlySetter.ts, 2, 10)) +>b : Symbol(b, Decl(declFileObjectLiteralWithOnlySetter.ts, 2, 12)) >a : Symbol(a, Decl(declFileObjectLiteralWithOnlySetter.ts, 4, 14)) }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types index 2f15818e0f2e5..bf62561f57d5f 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types @@ -15,9 +15,9 @@ function /*1*/makePoint(x: number) { >x : number >a : number >this.b = a : number ->this.b : any ->this : any ->b : any +>this.b : number +>this : { b: number; x: number; } +>b : number >a : number }; diff --git a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols index dbd5aa150dc5e..785a56546811d 100644 --- a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols +++ b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols @@ -8,11 +8,18 @@ var object = { get 0() { return this._0; +>this._0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) +>this : Symbol(object, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 12)) +>_0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) + }, set 0(x: number) { >x : Symbol(x, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 6, 10)) this._0 = x; +>this._0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) +>this : Symbol(object, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 12)) +>_0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) >x : Symbol(x, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 6, 10)) }, diff --git a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types index 32e5b33e41132..77026be2795c7 100644 --- a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types +++ b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types @@ -10,9 +10,9 @@ var object = { get 0() { return this._0; ->this._0 : any ->this : any ->_0 : any +>this._0 : number +>this : { _0: number; 0: number; } +>_0 : number }, set 0(x: number) { @@ -20,9 +20,9 @@ var object = { this._0 = x; >this._0 = x : number ->this._0 : any ->this : any ->_0 : any +>this._0 : number +>this : { _0: number; 0: number; } +>_0 : number >x : number }, diff --git a/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt b/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt index 5396f1f4316d5..eb2c93e7845cc 100644 --- a/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt +++ b/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(10,9): error TS2682: 'get' and 'set' accessor must have the same 'this' type. tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(11,9): error TS2682: 'get' and 'set' accessor must have the same 'this' type. -tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(16,22): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. -==== tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts (3 errors) ==== +==== tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts (2 errors) ==== interface Foo { n: number; x: number; @@ -24,7 +23,5 @@ tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(16,22): er n: 16, // there is no contextual this type from an Foo.x. get x() { return this.n; } - ~~~~ -!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. } \ No newline at end of file From ec292c92e292c0747cda0002445caab76de9e627 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 22 Feb 2017 19:25:19 -0800 Subject: [PATCH 10/26] Update test --- .../baselines/reference/thisTypeInAccessorsNegative.errors.txt | 1 - tests/baselines/reference/thisTypeInAccessorsNegative.js | 2 -- .../conformance/types/thisType/thisTypeInAccessorsNegative.ts | 1 - 3 files changed, 4 deletions(-) diff --git a/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt b/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt index eb2c93e7845cc..cd60967372353 100644 --- a/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt +++ b/tests/baselines/reference/thisTypeInAccessorsNegative.errors.txt @@ -21,7 +21,6 @@ tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts(11,9): err } const contextual: Foo = { n: 16, - // there is no contextual this type from an Foo.x. get x() { return this.n; } } \ No newline at end of file diff --git a/tests/baselines/reference/thisTypeInAccessorsNegative.js b/tests/baselines/reference/thisTypeInAccessorsNegative.js index 4d0826232f448..92e18f163c311 100644 --- a/tests/baselines/reference/thisTypeInAccessorsNegative.js +++ b/tests/baselines/reference/thisTypeInAccessorsNegative.js @@ -13,7 +13,6 @@ const mismatch = { } const contextual: Foo = { n: 16, - // there is no contextual this type from an Foo.x. get x() { return this.n; } } @@ -26,6 +25,5 @@ var mismatch = { }; var contextual = { n: 16, - // there is no contextual this type from an Foo.x. get x() { return this.n; } }; diff --git a/tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts b/tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts index 69ff4175a9261..67b7576a4b5fa 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInAccessorsNegative.ts @@ -15,6 +15,5 @@ const mismatch = { } const contextual: Foo = { n: 16, - // there is no contextual this type from an Foo.x. get x() { return this.n; } } From 9b6b6cc289a6afaeaba3ad6cb8310ad73ff62e80 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 22 Feb 2017 19:32:34 -0800 Subject: [PATCH 11/26] Fix linting error --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 69c294e97c2d4..8c1a91d203d55 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8991,7 +8991,7 @@ namespace ts { function getWidenedTypeOfObjectLiteral(type: Type): Type { const members = createMap(); - for (let prop of getPropertiesOfObjectType(type)) { + for (const prop of getPropertiesOfObjectType(type)) { // Since get accessors already widen their return value there is no need to // widen accessor based properties here. members.set(prop.name, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop) : prop); From 9dc2bae2e657dd4c4553b9c0f3e7bb91f9dc10bf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 24 Feb 2017 18:00:27 -0800 Subject: [PATCH 12/26] Use contextual type of object literal as 'this' in methods --- src/compiler/checker.ts | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8c1a91d203d55..0218f21a27fb6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11512,25 +11512,26 @@ namespace ts { const containingLiteral = getContainingObjectLiteral(func); if (containingLiteral) { // We have an object literal method. Check if the containing object literal has a contextual type - // and if that contextual type is or includes a ThisType. If so, T is the contextual type for - // 'this'. We continue looking in any directly enclosing object literals. - let objectLiteral = containingLiteral; - while (true) { - const type = getApparentTypeOfContextualType(objectLiteral); - if (type) { - const thisType = getThisTypeFromContextualType(type); - if (thisType) { - return thisType; - } - } - if (objectLiteral.parent.kind !== SyntaxKind.PropertyAssignment) { + // that includes a ThisType. If so, T is the contextual type for 'this'. We continue looking in + // any directly enclosing object literals. + const contextualType = getApparentTypeOfContextualType(containingLiteral); + let literal = containingLiteral; + let type = contextualType; + while (type) { + const thisType = getThisTypeFromContextualType(type); + if (thisType) { + return thisType; + } + if (literal.parent.kind !== SyntaxKind.PropertyAssignment) { break; } - objectLiteral = objectLiteral.parent.parent; + literal = literal.parent.parent; + type = getApparentTypeOfContextualType(literal); } // There was no contextual ThisType for the containing object literal, so the contextual type - // for 'this' is the type of the object literal itself. - return checkExpressionCached(containingLiteral); + // for 'this' is the contextual type for the containing object literal or the type of the object + // literal itself. + return contextualType || checkExpressionCached(containingLiteral); } // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the // contextual type for 'this' is 'obj'. From 16f403058fccec462c83ec7b7f9640e5f233ffd2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 24 Feb 2017 18:12:09 -0800 Subject: [PATCH 13/26] Accept new baselines --- tests/baselines/reference/castTest.symbols | 12 +-- tests/baselines/reference/castTest.types | 4 +- .../commentsOnObjectLiteral2.errors.txt | 5 +- .../reference/fixSignatureCaching.errors.txt | 98 +------------------ .../baselines/reference/objectSpread.symbols | 6 +- tests/baselines/reference/objectSpread.types | 2 +- .../reference/thisTypeInFunctions2.symbols | 18 ++-- .../reference/thisTypeInFunctions2.types | 18 ++-- 8 files changed, 30 insertions(+), 133 deletions(-) diff --git a/tests/baselines/reference/castTest.symbols b/tests/baselines/reference/castTest.symbols index 706f75a10287f..0baee00ec47d4 100644 --- a/tests/baselines/reference/castTest.symbols +++ b/tests/baselines/reference/castTest.symbols @@ -71,13 +71,13 @@ var p_cast = ({ return new Point(this.x + dx, this.y + dy); >Point : Symbol(Point, Decl(castTest.ts, 11, 37)) ->this.x : Symbol(x, Decl(castTest.ts, 22, 23)) ->this : Symbol(__object, Decl(castTest.ts, 22, 22)) ->x : Symbol(x, Decl(castTest.ts, 22, 23)) +>this.x : Symbol(Point.x, Decl(castTest.ts, 14, 1)) +>this : Symbol(Point, Decl(castTest.ts, 11, 37)) +>x : Symbol(Point.x, Decl(castTest.ts, 14, 1)) >dx : Symbol(dx, Decl(castTest.ts, 25, 18)) ->this.y : Symbol(y, Decl(castTest.ts, 23, 9)) ->this : Symbol(__object, Decl(castTest.ts, 22, 22)) ->y : Symbol(y, Decl(castTest.ts, 23, 9)) +>this.y : Symbol(Point.y, Decl(castTest.ts, 15, 14)) +>this : Symbol(Point, Decl(castTest.ts, 11, 37)) +>y : Symbol(Point.y, Decl(castTest.ts, 15, 14)) >dy : Symbol(dy, Decl(castTest.ts, 25, 21)) }, diff --git a/tests/baselines/reference/castTest.types b/tests/baselines/reference/castTest.types index acdc58d0b25f7..08c9853dca636 100644 --- a/tests/baselines/reference/castTest.types +++ b/tests/baselines/reference/castTest.types @@ -93,12 +93,12 @@ var p_cast = ({ >Point : typeof Point >this.x + dx : number >this.x : number ->this : { x: number; y: number; add: (dx: number, dy: number) => Point; mult: (p: Point) => Point; } +>this : Point >x : number >dx : number >this.y + dy : number >this.y : number ->this : { x: number; y: number; add: (dx: number, dy: number) => Point; mult: (p: Point) => Point; } +>this : Point >y : number >dy : number diff --git a/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt b/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt index 3748d0387b666..2a2394ced4860 100644 --- a/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt +++ b/tests/baselines/reference/commentsOnObjectLiteral2.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/commentsOnObjectLiteral2.ts(1,14): error TS2304: Cannot find name 'makeClass'. -tests/cases/compiler/commentsOnObjectLiteral2.ts(9,17): error TS2339: Property 'name' does not exist on type '{ initialize: (name: any) => void; }'. -==== tests/cases/compiler/commentsOnObjectLiteral2.ts (2 errors) ==== +==== tests/cases/compiler/commentsOnObjectLiteral2.ts (1 errors) ==== var Person = makeClass( ~~~~~~~~~ !!! error TS2304: Cannot find name 'makeClass'. @@ -14,8 +13,6 @@ tests/cases/compiler/commentsOnObjectLiteral2.ts(9,17): error TS2339: Property ' */ initialize: function(name) { this.name = name; - ~~~~ -!!! error TS2339: Property 'name' does not exist on type '{ initialize: (name: any) => void; }'. } /* trailing comment 1*/, } ); \ No newline at end of file diff --git a/tests/baselines/reference/fixSignatureCaching.errors.txt b/tests/baselines/reference/fixSignatureCaching.errors.txt index 284a0d1392641..7a5c43c966e2d 100644 --- a/tests/baselines/reference/fixSignatureCaching.errors.txt +++ b/tests/baselines/reference/fixSignatureCaching.errors.txt @@ -41,51 +41,19 @@ tests/cases/conformance/fixSignatureCaching.ts(639,38): error TS2304: Cannot fin tests/cases/conformance/fixSignatureCaching.ts(640,13): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(641,13): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(704,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(704,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(704,58): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(704,67): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(705,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(734,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(734,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(734,58): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(734,67): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(735,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(783,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(783,45): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(783,58): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(783,67): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(784,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(804,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(805,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(805,46): error TS2339: Property 'findMatch' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(805,61): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(805,89): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(807,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(827,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(828,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(828,47): error TS2339: Property 'findMatches' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(828,64): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(828,92): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(830,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(844,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(845,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(845,39): error TS2339: Property 'detectOS' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(845,53): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(847,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(869,25): error TS2339: Property 'getVersion' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(869,46): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(890,25): error TS2339: Property 'getVersionStr' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(890,49): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(912,36): error TS2339: Property 'findMatches' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(912,53): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(912,83): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(927,38): error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(941,33): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'. -tests/cases/conformance/fixSignatureCaching.ts(941,68): error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(951,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. -tests/cases/conformance/fixSignatureCaching.ts(952,22): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(952,42): error TS2339: Property 'mobileGrade' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(954,25): error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. tests/cases/conformance/fixSignatureCaching.ts(959,16): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(959,42): error TS2304: Cannot find name 'window'. tests/cases/conformance/fixSignatureCaching.ts(960,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'. @@ -103,7 +71,7 @@ tests/cases/conformance/fixSignatureCaching.ts(979,23): error TS2304: Cannot fin tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot find name 'window'. -==== tests/cases/conformance/fixSignatureCaching.ts (103 errors) ==== +==== tests/cases/conformance/fixSignatureCaching.ts (71 errors) ==== // Repro from #10697 (function (define, undefined) { @@ -894,15 +862,7 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. - ~~~~~~~~~~~~~ -!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. return this._cache.mobile; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -934,15 +894,7 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. - ~~~~~~~~~~~~~ -!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. return this._cache.phone; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -993,15 +945,7 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'. - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. - ~~~~~~~~~~~~~ -!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. return this._cache.tablet; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1022,21 +966,13 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ userAgent: function () { if (this._cache.userAgent === undefined) { - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua); - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~~ !!! error TS2339: Property 'findMatch' does not exist on type '{}'. ~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } return this._cache.userAgent; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1057,21 +993,13 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ userAgents: function () { if (this._cache.userAgents === undefined) { - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua); - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~~~~ !!! error TS2339: Property 'findMatches' does not exist on type '{}'. ~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } return this._cache.userAgents; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1086,19 +1014,11 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ os: function () { if (this._cache.os === undefined) { - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.os = impl.detectOS(this.ua); - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~ !!! error TS2339: Property 'detectOS' does not exist on type '{}'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } return this._cache.os; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1123,8 +1043,6 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin return impl.getVersion(key, this.ua); ~~~~~~~~~~ !!! error TS2339: Property 'getVersion' does not exist on type '{}'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1148,8 +1066,6 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin return impl.getVersionStr(key, this.ua); ~~~~~~~~~~~~~ !!! error TS2339: Property 'getVersionStr' does not exist on type '{}'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1176,8 +1092,6 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin !!! error TS2339: Property 'findMatches' does not exist on type '{}'. ~~~~~~~~~~~~~~~~~ !!! error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1193,8 +1107,6 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin pattern = new RegExp(pattern, 'i'); } return pattern.test(this.ua); - ~~ -!!! error TS2339: Property 'ua' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1211,8 +1123,6 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth); ~~~~~~~~~~~~ !!! error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'. - ~~~~~~~~~~~~~ -!!! error TS2339: Property 'maxPhoneWidth' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. }, /** @@ -1223,17 +1133,11 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin */ mobileGrade: function () { if (this._cache.grade === undefined) { - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. this._cache.grade = impl.mobileGrade(this); - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. ~~~~~~~~~~~ !!! error TS2339: Property 'mobileGrade' does not exist on type '{}'. } return this._cache.grade; - ~~~~~~ -!!! error TS2339: Property '_cache' does not exist on type '{ constructor: (userAgent: any, maxPhoneWidth: any) => void; mobile: () => any; phone: () => any; tablet: () => any; userAgent: () => any; userAgents: () => any; os: () => any; version: (key: any) => any; versionStr: (key: any) => any; is: (key: any) => any; match: (pattern: any) => any; isPhoneSized: (maxPhoneWidth: any) => any; mobileGrade: () => any; }'. } }; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index a734066d5e714..0538121e90c13 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -200,9 +200,9 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) >c : Symbol(c, Decl(objectSpread.ts, 45, 3)) >plus : Symbol(plus, Decl(objectSpread.ts, 49, 48)) ->this.p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) ->this : Symbol(cplus, Decl(objectSpread.ts, 49, 40)) ->p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) +>this.p : Symbol(p, Decl(objectSpread.ts, 49, 12)) +>this : Symbol(cplus, Decl(objectSpread.ts, 49, 10)) +>p : Symbol(p, Decl(objectSpread.ts, 49, 12)) cplus.plus(); >cplus.plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index b6ad1d13ae4eb..3a73672142525 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -268,7 +268,7 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >plus : () => number >this.p + 1 : number >this.p : number ->this : { plus(): number; p: number; } +>this : { p: number; plus(): void; } >p : number >1 : 1 diff --git a/tests/baselines/reference/thisTypeInFunctions2.symbols b/tests/baselines/reference/thisTypeInFunctions2.symbols index d9d0be723b61a..6811ef4a23472 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.symbols +++ b/tests/baselines/reference/thisTypeInFunctions2.symbols @@ -90,12 +90,10 @@ extend2({ >init : Symbol(init, Decl(thisTypeInFunctions2.ts, 32, 9)) this // this: containing object literal type ->this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) +>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) this.mine ->this.mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) ->this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) ->mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) +>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) //this.willDestroy }, @@ -106,12 +104,10 @@ extend2({ >foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 38, 13)) this // this: containing object literal type ->this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) +>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) this.mine ->this.mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) ->this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 32, 8)) ->mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) +>this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) } }); @@ -126,9 +122,9 @@ simple({ >n.length : Symbol(String.length, Decl(lib.d.ts, --, --)) >n : Symbol(n, Decl(thisTypeInFunctions2.ts, 46, 8)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->this.bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 48, 6)) ->this : Symbol(__object, Decl(thisTypeInFunctions2.ts, 45, 7)) ->bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 48, 6)) +>this.bar : Symbol(SimpleInterface.bar, Decl(thisTypeInFunctions2.ts, 13, 19)) +>this : Symbol(SimpleInterface, Decl(thisTypeInFunctions2.ts, 11, 1)) +>bar : Symbol(SimpleInterface.bar, Decl(thisTypeInFunctions2.ts, 13, 19)) }, bar() { diff --git a/tests/baselines/reference/thisTypeInFunctions2.types b/tests/baselines/reference/thisTypeInFunctions2.types index f79426529eaa5..79169a715d5ce 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.types +++ b/tests/baselines/reference/thisTypeInFunctions2.types @@ -100,12 +100,12 @@ extend2({ >init : () => void this // this: containing object literal type ->this : { init(): void; mine: number; foo(): void; } +>this : IndexedWithoutThis this.mine ->this.mine : number ->this : { init(): void; mine: number; foo(): void; } ->mine : number +>this.mine : any +>this : IndexedWithoutThis +>mine : any //this.willDestroy }, @@ -117,12 +117,12 @@ extend2({ >foo : () => void this // this: containing object literal type ->this : { init(): void; mine: number; foo(): void; } +>this : IndexedWithoutThis this.mine ->this.mine : number ->this : { init(): void; mine: number; foo(): void; } ->mine : number +>this.mine : any +>this : IndexedWithoutThis +>mine : any } }); @@ -142,7 +142,7 @@ simple({ >length : number >this.bar() : number >this.bar : () => number ->this : { foo(n: string): number; bar(): number; } +>this : SimpleInterface >bar : () => number }, From 20b4523d0ffa92454ddb3ed683c8c89a14e46ef5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 24 Feb 2017 19:52:22 -0800 Subject: [PATCH 14/26] Rename applyToContextualType to mapType and remove old mapType --- src/compiler/checker.ts | 60 +++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0218f21a27fb6..f451871d2bbf6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10041,8 +10041,31 @@ namespace ts { return f(type) ? type : neverType; } - function mapType(type: Type, f: (t: Type) => Type): Type { - return type.flags & TypeFlags.Union ? getUnionType(map((type).types, f)) : f(type); + // Apply a mapping function to a contextual type and return the resulting type. If the contextual type + // is a union type, the mapping function is applied to each constituent type and a union of the resulting + // types is returned. + function mapType(type: Type, mapper: (t: Type) => Type): Type { + if (!(type.flags & TypeFlags.Union)) { + return mapper(type); + } + const types = (type).types; + let mappedType: Type; + let mappedTypes: Type[]; + for (const current of types) { + const t = mapper(current); + if (t) { + if (!mappedType) { + mappedType = t; + } + else if (!mappedTypes) { + mappedTypes = [mappedType, t]; + } + else { + mappedTypes.push(t); + } + } + } + return mappedTypes ? getUnionType(mappedTypes) : mappedType; } function extractTypesOfKind(type: Type, kind: TypeFlags) { @@ -11491,7 +11514,7 @@ namespace ts { } function getThisTypeFromContextualType(type: Type): Type { - return applyToContextualType(type, t => { + return mapType(type, t => { return t.flags & TypeFlags.Intersection ? forEach((t).types, getThisTypeArgument) : getThisTypeArgument(t); }); } @@ -11739,42 +11762,15 @@ namespace ts { return undefined; } - // Apply a mapping function to a contextual type and return the resulting type. If the contextual type - // is a union type, the mapping function is applied to each constituent type and a union of the resulting - // types is returned. - function applyToContextualType(type: Type, mapper: (t: Type) => Type): Type { - if (!(type.flags & TypeFlags.Union)) { - return mapper(type); - } - const types = (type).types; - let mappedType: Type; - let mappedTypes: Type[]; - for (const current of types) { - const t = mapper(current); - if (t) { - if (!mappedType) { - mappedType = t; - } - else if (!mappedTypes) { - mappedTypes = [mappedType, t]; - } - else { - mappedTypes.push(t); - } - } - } - return mappedTypes ? getUnionType(mappedTypes) : mappedType; - } - function getTypeOfPropertyOfContextualType(type: Type, name: string) { - return applyToContextualType(type, t => { + return mapType(type, t => { const prop = t.flags & TypeFlags.StructuredType ? getPropertyOfType(t, name) : undefined; return prop ? getTypeOfSymbol(prop) : undefined; }); } function getIndexTypeOfContextualType(type: Type, kind: IndexKind) { - return applyToContextualType(type, t => getIndexTypeOfStructuredType(t, kind)); + return mapType(type, t => getIndexTypeOfStructuredType(t, kind)); } // Return true if the given contextual type is a tuple-like type From 6fdd929a66ef6cb9eb7ec5b092b079ac1eb4b0ff Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 24 Feb 2017 19:52:50 -0800 Subject: [PATCH 15/26] Update test --- tests/baselines/reference/thisTypeInFunctions2.js | 2 -- .../reference/thisTypeInFunctions2.symbols | 13 ++++++------- .../baselines/reference/thisTypeInFunctions2.types | 5 ++--- .../types/thisType/thisTypeInFunctions2.ts | 1 - 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/baselines/reference/thisTypeInFunctions2.js b/tests/baselines/reference/thisTypeInFunctions2.js index 45b26fe84d845..978f79483b03a 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.js +++ b/tests/baselines/reference/thisTypeInFunctions2.js @@ -35,7 +35,6 @@ extend2({ init() { this // this: containing object literal type this.mine - //this.willDestroy }, mine: 13, foo() { @@ -71,7 +70,6 @@ extend2({ init: function () { this; // this: containing object literal type this.mine; - //this.willDestroy }, mine: 13, foo: function () { diff --git a/tests/baselines/reference/thisTypeInFunctions2.symbols b/tests/baselines/reference/thisTypeInFunctions2.symbols index 6811ef4a23472..d4b19caddb41d 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.symbols +++ b/tests/baselines/reference/thisTypeInFunctions2.symbols @@ -95,13 +95,12 @@ extend2({ this.mine >this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) - //this.willDestroy }, mine: 13, ->mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 37, 6)) +>mine : Symbol(mine, Decl(thisTypeInFunctions2.ts, 36, 6)) foo() { ->foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 38, 13)) +>foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 37, 13)) this // this: containing object literal type >this : Symbol(IndexedWithoutThis, Decl(thisTypeInFunctions2.ts, 5, 1)) @@ -115,12 +114,12 @@ simple({ >simple : Symbol(simple, Decl(thisTypeInFunctions2.ts, 17, 57)) foo(n) { ->foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 45, 8)) ->n : Symbol(n, Decl(thisTypeInFunctions2.ts, 46, 8)) +>foo : Symbol(foo, Decl(thisTypeInFunctions2.ts, 44, 8)) +>n : Symbol(n, Decl(thisTypeInFunctions2.ts, 45, 8)) return n.length + this.bar(); >n.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->n : Symbol(n, Decl(thisTypeInFunctions2.ts, 46, 8)) +>n : Symbol(n, Decl(thisTypeInFunctions2.ts, 45, 8)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) >this.bar : Symbol(SimpleInterface.bar, Decl(thisTypeInFunctions2.ts, 13, 19)) >this : Symbol(SimpleInterface, Decl(thisTypeInFunctions2.ts, 11, 1)) @@ -128,7 +127,7 @@ simple({ }, bar() { ->bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 48, 6)) +>bar : Symbol(bar, Decl(thisTypeInFunctions2.ts, 47, 6)) return 14; } diff --git a/tests/baselines/reference/thisTypeInFunctions2.types b/tests/baselines/reference/thisTypeInFunctions2.types index 79169a715d5ce..a527429ccd9ce 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.types +++ b/tests/baselines/reference/thisTypeInFunctions2.types @@ -92,9 +92,9 @@ extend1({ } }); extend2({ ->extend2({ init() { this // this: containing object literal type this.mine //this.willDestroy }, mine: 13, foo() { this // this: containing object literal type this.mine }}) : void +>extend2({ init() { this // this: containing object literal type this.mine }, mine: 13, foo() { this // this: containing object literal type this.mine }}) : void >extend2 : (args: IndexedWithoutThis) => void ->{ init() { this // this: containing object literal type this.mine //this.willDestroy }, mine: 13, foo() { this // this: containing object literal type this.mine }} : { init(): void; mine: number; foo(): void; } +>{ init() { this // this: containing object literal type this.mine }, mine: 13, foo() { this // this: containing object literal type this.mine }} : { init(): void; mine: number; foo(): void; } init() { >init : () => void @@ -107,7 +107,6 @@ extend2({ >this : IndexedWithoutThis >mine : any - //this.willDestroy }, mine: 13, >mine : number diff --git a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts index 0d1581633c3e9..1c80e21aa160a 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts @@ -34,7 +34,6 @@ extend2({ init() { this // this: containing object literal type this.mine - //this.willDestroy }, mine: 13, foo() { From cd87d903a022a5aa2e94f57cb7fb9abc646aa61e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Feb 2017 10:19:14 -0800 Subject: [PATCH 16/26] Update comment --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f451871d2bbf6..ff3a1079b189a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10041,9 +10041,9 @@ namespace ts { return f(type) ? type : neverType; } - // Apply a mapping function to a contextual type and return the resulting type. If the contextual type - // is a union type, the mapping function is applied to each constituent type and a union of the resulting - // types is returned. + // Apply a mapping function to a type and return the resulting type. If the source type + // is a union type, the mapping function is applied to each constituent type and a union + // of the resulting types is returned. function mapType(type: Type, mapper: (t: Type) => Type): Type { if (!(type.flags & TypeFlags.Union)) { return mapper(type); From 5bda48ba8d44717cb7038c70d365438de69ce09b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Feb 2017 10:19:26 -0800 Subject: [PATCH 17/26] Add tests --- .../reference/thisTypeInObjectLiterals2.js | 293 +++++++++++ .../thisTypeInObjectLiterals2.symbols | 410 ++++++++++++++++ .../reference/thisTypeInObjectLiterals2.types | 463 ++++++++++++++++++ .../thisType/thisTypeInObjectLiterals2.ts | 144 ++++++ 4 files changed, 1310 insertions(+) create mode 100644 tests/baselines/reference/thisTypeInObjectLiterals2.js create mode 100644 tests/baselines/reference/thisTypeInObjectLiterals2.symbols create mode 100644 tests/baselines/reference/thisTypeInObjectLiterals2.types create mode 100644 tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.js b/tests/baselines/reference/thisTypeInObjectLiterals2.js new file mode 100644 index 0000000000000..08f02b6c5afda --- /dev/null +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.js @@ -0,0 +1,293 @@ +//// [thisTypeInObjectLiterals2.ts] + +// In methods of an object literal with no contextual type, 'this' has the type +// of the object literal. + +let obj1 = { + a: 1, + f() { + return this.a; + }, + b: "hello", + c: { + g() { + this.g(); + } + }, + get d() { + return this.a; + }, + get e() { + return this.b; + }, + set e(value) { + this.b = value; + } +}; + +// In methods of an object literal with a contextual type, 'this' has the +// contextual type. + +type Point = { + x: number; + y: number; + moveBy(dx: number, dy: number): void; +} + +let p1: Point = { + x: 10, + y: 20, + moveBy(dx, dy) { + this.x += dx; + this.y += dy; + } +}; + +declare function f1(p: Point): void; + +f1({ + x: 10, + y: 20, + moveBy(dx, dy) { + this.x += dx; + this.y += dy; + } +}); + +// In methods of an object literal with a contextual type that includes some +// ThisType, 'this' is of type T. + +type ObjectDescriptor = { + data?: D; + methods?: M & ThisType; // Type of 'this' in methods is D & M +} + +declare function makeObject(desc: ObjectDescriptor): D & M; + +let x1 = makeObject({ + data: { x: 0, y: 0 }, + methods: { + moveBy(dx: number, dy: number) { + this.x += dx; // Strongly typed this + this.y += dy; // Strongly typed this + } + } +}); + +// In methods contained in an object literal with a contextual type that includes +// some ThisType, 'this' is of type T. + +type ObjectDescriptor2 = ThisType & { + data?: D; + methods?: M; +} + +declare function makeObject2(desc: ObjectDescriptor): D & M; + +let x2 = makeObject2({ + data: { x: 0, y: 0 }, + methods: { + moveBy(dx: number, dy: number) { + this.x += dx; // Strongly typed this + this.y += dy; // Strongly typed this + } + } +}); + +// Proof of concept for typing of Vue.js + +type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; + +type Dictionary = { [x: string]: T } + +type Computed = { + get?(): T; + set?(value: T): void; +} + +type VueOptions = ThisType & { + data?: D | (() => D); + methods?: M; + computed?: Accessors

; +} + +declare const Vue: new (options: VueOptions) => D & M & P; + +let vue = new Vue({ + data: () => ({ x: 1, y: 2 }), + methods: { + f(x: string) { + return this.x; + } + }, + computed: { + test(): number { + return this.x; + }, + hello: { + get() { + return "hi"; + }, + set(value: string) { + } + } + } +}); + +vue; +vue.x; +vue.f("abc"); +vue.test; +vue.hello; + + +//// [thisTypeInObjectLiterals2.js] +// In methods of an object literal with no contextual type, 'this' has the type +// of the object literal. +var obj1 = { + a: 1, + f: function () { + return this.a; + }, + b: "hello", + c: { + g: function () { + this.g(); + } + }, + get d() { + return this.a; + }, + get e() { + return this.b; + }, + set e(value) { + this.b = value; + } +}; +var p1 = { + x: 10, + y: 20, + moveBy: function (dx, dy) { + this.x += dx; + this.y += dy; + } +}; +f1({ + x: 10, + y: 20, + moveBy: function (dx, dy) { + this.x += dx; + this.y += dy; + } +}); +var x1 = makeObject({ + data: { x: 0, y: 0 }, + methods: { + moveBy: function (dx, dy) { + this.x += dx; // Strongly typed this + this.y += dy; // Strongly typed this + } + } +}); +var x2 = makeObject2({ + data: { x: 0, y: 0 }, + methods: { + moveBy: function (dx, dy) { + this.x += dx; // Strongly typed this + this.y += dy; // Strongly typed this + } + } +}); +var vue = new Vue({ + data: function () { return ({ x: 1, y: 2 }); }, + methods: { + f: function (x) { + return this.x; + } + }, + computed: { + test: function () { + return this.x; + }, + hello: { + get: function () { + return "hi"; + }, + set: function (value) { + } + } + } +}); +vue; +vue.x; +vue.f("abc"); +vue.test; +vue.hello; + + +//// [thisTypeInObjectLiterals2.d.ts] +declare let obj1: { + a: number; + f(): number; + b: string; + c: { + g(): void; + }; + readonly d: number; + e: string; +}; +declare type Point = { + x: number; + y: number; + moveBy(dx: number, dy: number): void; +}; +declare let p1: Point; +declare function f1(p: Point): void; +declare type ObjectDescriptor = { + data?: D; + methods?: M & ThisType; +}; +declare function makeObject(desc: ObjectDescriptor): D & M; +declare let x1: { + x: number; + y: number; +} & { + moveBy(dx: number, dy: number): void; +}; +declare type ObjectDescriptor2 = ThisType & { + data?: D; + methods?: M; +}; +declare function makeObject2(desc: ObjectDescriptor): D & M; +declare let x2: { + x: number; + y: number; +} & { + moveBy(dx: number, dy: number): void; +}; +declare type Accessors = { + [K in keyof T]: (() => T[K]) | Computed; +}; +declare type Dictionary = { + [x: string]: T; +}; +declare type Computed = { + get?(): T; + set?(value: T): void; +}; +declare type VueOptions = ThisType & { + data?: D | (() => D); + methods?: M; + computed?: Accessors

; +}; +declare const Vue: new (options: VueOptions) => D & M & P; +declare let vue: { + x: number; + y: number; +} & { + f(x: string): number; +} & { + test: number; + hello: string; +}; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.symbols b/tests/baselines/reference/thisTypeInObjectLiterals2.symbols new file mode 100644 index 0000000000000..ef72c320cce23 --- /dev/null +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.symbols @@ -0,0 +1,410 @@ +=== tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts === + +// In methods of an object literal with no contextual type, 'this' has the type +// of the object literal. + +let obj1 = { +>obj1 : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 3)) + + a: 1, +>a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12)) + + f() { +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 5, 9)) + + return this.a; +>this.a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12)) +>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10)) +>a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12)) + + }, + b: "hello", +>b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6)) + + c: { +>c : Symbol(c, Decl(thisTypeInObjectLiterals2.ts, 9, 15)) + + g() { +>g : Symbol(g, Decl(thisTypeInObjectLiterals2.ts, 10, 8)) + + this.g(); +>this.g : Symbol(g, Decl(thisTypeInObjectLiterals2.ts, 10, 8)) +>this : Symbol(__object, Decl(thisTypeInObjectLiterals2.ts, 10, 6)) +>g : Symbol(g, Decl(thisTypeInObjectLiterals2.ts, 10, 8)) + } + }, + get d() { +>d : Symbol(d, Decl(thisTypeInObjectLiterals2.ts, 14, 6)) + + return this.a; +>this.a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12)) +>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10)) +>a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12)) + + }, + get e() { +>e : Symbol(e, Decl(thisTypeInObjectLiterals2.ts, 17, 6), Decl(thisTypeInObjectLiterals2.ts, 20, 6)) + + return this.b; +>this.b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6)) +>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10)) +>b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6)) + + }, + set e(value) { +>e : Symbol(e, Decl(thisTypeInObjectLiterals2.ts, 17, 6), Decl(thisTypeInObjectLiterals2.ts, 20, 6)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 21, 10)) + + this.b = value; +>this.b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6)) +>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10)) +>b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 21, 10)) + } +}; + +// In methods of an object literal with a contextual type, 'this' has the +// contextual type. + +type Point = { +>Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2)) + + x: number; +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) + + y: number; +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) + + moveBy(dx: number, dy: number): void; +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 32, 11)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 32, 22)) +} + +let p1: Point = { +>p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 35, 3)) +>Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2)) + + x: 10, +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 35, 17)) + + y: 20, +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 36, 10)) + + moveBy(dx, dy) { +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 37, 10)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 38, 11)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 38, 14)) + + this.x += dx; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 38, 11)) + + this.y += dy; +>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 38, 14)) + } +}; + +declare function f1(p: Point): void; +>f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 42, 2)) +>p : Symbol(p, Decl(thisTypeInObjectLiterals2.ts, 44, 20)) +>Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2)) + +f1({ +>f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 42, 2)) + + x: 10, +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 46, 4)) + + y: 20, +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 47, 10)) + + moveBy(dx, dy) { +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 48, 10)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 49, 11)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 49, 14)) + + this.x += dx; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 49, 11)) + + this.y += dy; +>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 49, 14)) + } +}); + +// In methods of an object literal with a contextual type that includes some +// ThisType, 'this' is of type T. + +type ObjectDescriptor = { +>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24)) + + data?: D; +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 58, 31)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22)) + + methods?: M & ThisType; // Type of 'this' in methods is D & M +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 59, 13)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24)) +>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24)) +} + +declare function makeObject(desc: ObjectDescriptor): D & M; +>makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 61, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30)) +>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 63, 34)) +>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30)) + +let x1 = makeObject({ +>x1 : Symbol(x1, Decl(thisTypeInObjectLiterals2.ts, 65, 3)) +>makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 61, 1)) + + data: { x: 0, y: 0 }, +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 65, 21)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17)) + + methods: { +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 66, 25)) + + moveBy(dx: number, dy: number) { +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 67, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 68, 15)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 68, 26)) + + this.x += dx; // Strongly typed this +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 68, 15)) + + this.y += dy; // Strongly typed this +>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 68, 26)) + } + } +}); + +// In methods contained in an object literal with a contextual type that includes +// some ThisType, 'this' is of type T. + +type ObjectDescriptor2 = ThisType & { +>ObjectDescriptor2 : Symbol(ObjectDescriptor2, Decl(thisTypeInObjectLiterals2.ts, 73, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25)) +>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25)) + + data?: D; +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 78, 50)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23)) + + methods?: M; +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 79, 13)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25)) +} + +declare function makeObject2(desc: ObjectDescriptor): D & M; +>makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 81, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31)) +>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 83, 35)) +>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31)) + +let x2 = makeObject2({ +>x2 : Symbol(x2, Decl(thisTypeInObjectLiterals2.ts, 85, 3)) +>makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 81, 1)) + + data: { x: 0, y: 0 }, +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 85, 22)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17)) + + methods: { +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 86, 25)) + + moveBy(dx: number, dy: number) { +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 87, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 88, 15)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 88, 26)) + + this.x += dx; // Strongly typed this +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 88, 15)) + + this.y += dy; // Strongly typed this +>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 88, 26)) + } + } +}); + +// Proof of concept for typing of Vue.js + +type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; +>Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 93, 3)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23)) +>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 99, 39)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23)) + +type Dictionary = { [x: string]: T } +>Dictionary : Symbol(Dictionary, Decl(thisTypeInObjectLiterals2.ts, 97, 70)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 99, 16)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 99, 24)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 99, 16)) + +type Computed = { +>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 99, 39)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14)) + + get?(): T; +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 101, 20)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14)) + + set?(value: T): void; +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 102, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 103, 9)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14)) +} + +type VueOptions = ThisType & { +>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 104, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21)) +>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21)) + + data?: D | (() => D); +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 106, 50)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) + + methods?: M; +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 107, 25)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18)) + + computed?: Accessors

; +>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 108, 16)) +>Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 93, 3)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21)) +} + +declare const Vue: new (options: VueOptions) => D & M & P; +>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 112, 13)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29)) +>options : Symbol(options, Decl(thisTypeInObjectLiterals2.ts, 112, 33)) +>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 104, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29)) + +let vue = new Vue({ +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) +>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 112, 13)) + + data: () => ({ x: 1, y: 2 }), +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 114, 19)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 115, 24)) + + methods: { +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 115, 33)) + + f(x: string) { +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 117, 10)) + + return this.x; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) + } + }, + computed: { +>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 120, 6)) + + test(): number { +>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15)) + + return this.x; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) + + }, + hello: { +>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10)) + + get() { +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 125, 16)) + + return "hi"; + }, + set(value: string) { +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 128, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 129, 16)) + } + } + } +}); + +vue; +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) + +vue.x; +>vue.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) + +vue.f("abc"); +>vue.f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14)) + +vue.test; +>vue.test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) +>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15)) + +vue.hello; +>vue.hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) +>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10)) + diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.types b/tests/baselines/reference/thisTypeInObjectLiterals2.types new file mode 100644 index 0000000000000..39fd922f6179b --- /dev/null +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.types @@ -0,0 +1,463 @@ +=== tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts === + +// In methods of an object literal with no contextual type, 'this' has the type +// of the object literal. + +let obj1 = { +>obj1 : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; } +>{ a: 1, f() { return this.a; }, b: "hello", c: { g() { this.g(); } }, get d() { return this.a; }, get e() { return this.b; }, set e(value) { this.b = value; }} : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; } + + a: 1, +>a : number +>1 : 1 + + f() { +>f : () => number + + return this.a; +>this.a : number +>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; } +>a : number + + }, + b: "hello", +>b : string +>"hello" : "hello" + + c: { +>c : { g(): void; } +>{ g() { this.g(); } } : { g(): void; } + + g() { +>g : () => void + + this.g(); +>this.g() : void +>this.g : () => void +>this : { g(): void; } +>g : () => void + } + }, + get d() { +>d : number + + return this.a; +>this.a : number +>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; } +>a : number + + }, + get e() { +>e : string + + return this.b; +>this.b : string +>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; } +>b : string + + }, + set e(value) { +>e : string +>value : string + + this.b = value; +>this.b = value : string +>this.b : string +>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; } +>b : string +>value : string + } +}; + +// In methods of an object literal with a contextual type, 'this' has the +// contextual type. + +type Point = { +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + + moveBy(dx: number, dy: number): void; +>moveBy : (dx: number, dy: number) => void +>dx : number +>dy : number +} + +let p1: Point = { +>p1 : Point +>Point : Point +>{ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }} : { x: number; y: number; moveBy(dx: number, dy: number): void; } + + x: 10, +>x : number +>10 : 10 + + y: 20, +>y : number +>20 : 20 + + moveBy(dx, dy) { +>moveBy : (dx: number, dy: number) => void +>dx : number +>dy : number + + this.x += dx; +>this.x += dx : number +>this.x : number +>this : Point +>x : number +>dx : number + + this.y += dy; +>this.y += dy : number +>this.y : number +>this : Point +>y : number +>dy : number + } +}; + +declare function f1(p: Point): void; +>f1 : (p: Point) => void +>p : Point +>Point : Point + +f1({ +>f1({ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }}) : void +>f1 : (p: Point) => void +>{ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }} : { x: number; y: number; moveBy(dx: number, dy: number): void; } + + x: 10, +>x : number +>10 : 10 + + y: 20, +>y : number +>20 : 20 + + moveBy(dx, dy) { +>moveBy : (dx: number, dy: number) => void +>dx : number +>dy : number + + this.x += dx; +>this.x += dx : number +>this.x : number +>this : Point +>x : number +>dx : number + + this.y += dy; +>this.y += dy : number +>this.y : number +>this : Point +>y : number +>dy : number + } +}); + +// In methods of an object literal with a contextual type that includes some +// ThisType, 'this' is of type T. + +type ObjectDescriptor = { +>ObjectDescriptor : ObjectDescriptor +>D : D +>M : M + + data?: D; +>data : D +>D : D + + methods?: M & ThisType; // Type of 'this' in methods is D & M +>methods : M & ThisType +>M : M +>ThisType : ThisType +>D : D +>M : M +} + +declare function makeObject(desc: ObjectDescriptor): D & M; +>makeObject : (desc: ObjectDescriptor) => D & M +>D : D +>M : M +>desc : ObjectDescriptor +>ObjectDescriptor : ObjectDescriptor +>D : D +>M : M +>D : D +>M : M + +let x1 = makeObject({ +>x1 : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>makeObject({ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }}) : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>makeObject : (desc: ObjectDescriptor) => D & M +>{ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }} : { data: { x: number; y: number; }; methods: { moveBy(dx: number, dy: number): void; }; } + + data: { x: 0, y: 0 }, +>data : { x: number; y: number; } +>{ x: 0, y: 0 } : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + methods: { +>methods : { moveBy(dx: number, dy: number): void; } +>{ moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } } : { moveBy(dx: number, dy: number): void; } + + moveBy(dx: number, dy: number) { +>moveBy : (dx: number, dy: number) => void +>dx : number +>dy : number + + this.x += dx; // Strongly typed this +>this.x += dx : number +>this.x : number +>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>x : number +>dx : number + + this.y += dy; // Strongly typed this +>this.y += dy : number +>this.y : number +>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>y : number +>dy : number + } + } +}); + +// In methods contained in an object literal with a contextual type that includes +// some ThisType, 'this' is of type T. + +type ObjectDescriptor2 = ThisType & { +>ObjectDescriptor2 : ObjectDescriptor2 +>D : D +>M : M +>ThisType : ThisType +>D : D +>M : M + + data?: D; +>data : D +>D : D + + methods?: M; +>methods : M +>M : M +} + +declare function makeObject2(desc: ObjectDescriptor): D & M; +>makeObject2 : (desc: ObjectDescriptor) => D & M +>D : D +>M : M +>desc : ObjectDescriptor +>ObjectDescriptor : ObjectDescriptor +>D : D +>M : M +>D : D +>M : M + +let x2 = makeObject2({ +>x2 : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>makeObject2({ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }}) : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>makeObject2 : (desc: ObjectDescriptor) => D & M +>{ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }} : { data: { x: number; y: number; }; methods: { moveBy(dx: number, dy: number): void; }; } + + data: { x: 0, y: 0 }, +>data : { x: number; y: number; } +>{ x: 0, y: 0 } : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>0 : 0 + + methods: { +>methods : { moveBy(dx: number, dy: number): void; } +>{ moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } } : { moveBy(dx: number, dy: number): void; } + + moveBy(dx: number, dy: number) { +>moveBy : (dx: number, dy: number) => void +>dx : number +>dy : number + + this.x += dx; // Strongly typed this +>this.x += dx : number +>this.x : number +>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>x : number +>dx : number + + this.y += dy; // Strongly typed this +>this.y += dy : number +>this.y : number +>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; } +>y : number +>dy : number + } + } +}); + +// Proof of concept for typing of Vue.js + +type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; +>Accessors : Accessors +>T : T +>K : K +>T : T +>T : T +>K : K +>Computed : Computed +>T : T +>K : K + +type Dictionary = { [x: string]: T } +>Dictionary : Dictionary +>T : T +>x : string +>T : T + +type Computed = { +>Computed : Computed +>T : T + + get?(): T; +>get : () => T +>T : T + + set?(value: T): void; +>set : (value: T) => void +>value : T +>T : T +} + +type VueOptions = ThisType & { +>VueOptions : VueOptions +>D : D +>M : M +>P : P +>ThisType : ThisType +>D : D +>M : M +>P : P + + data?: D | (() => D); +>data : D | (() => D) +>D : D +>D : D + + methods?: M; +>methods : M +>M : M + + computed?: Accessors

; +>computed : Accessors

+>Accessors : Accessors +>P : P +} + +declare const Vue: new (options: VueOptions) => D & M & P; +>Vue : new (options: VueOptions) => D & M & P +>D : D +>M : M +>P : P +>options : VueOptions +>VueOptions : VueOptions +>D : D +>M : M +>P : P +>D : D +>M : M +>P : P + +let vue = new Vue({ +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>Vue : new (options: VueOptions) => D & M & P +>{ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }} : { data: () => { x: number; y: number; }; methods: { f(x: string): number; }; computed: { test(): number; hello: { get(): string; set(value: string): void; }; }; } + + data: () => ({ x: 1, y: 2 }), +>data : () => { x: number; y: number; } +>() => ({ x: 1, y: 2 }) : () => { x: number; y: number; } +>({ x: 1, y: 2 }) : { x: number; y: number; } +>{ x: 1, y: 2 } : { x: number; y: number; } +>x : number +>1 : 1 +>y : number +>2 : 2 + + methods: { +>methods : { f(x: string): number; } +>{ f(x: string) { return this.x; } } : { f(x: string): number; } + + f(x: string) { +>f : (x: string) => number +>x : string + + return this.x; +>this.x : number +>this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>x : number + } + }, + computed: { +>computed : { test(): number; hello: { get(): string; set(value: string): void; }; } +>{ test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } } : { test(): number; hello: { get(): string; set(value: string): void; }; } + + test(): number { +>test : () => number + + return this.x; +>this.x : number +>this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>x : number + + }, + hello: { +>hello : { get(): string; set(value: string): void; } +>{ get() { return "hi"; }, set(value: string) { } } : { get(): string; set(value: string): void; } + + get() { +>get : () => string + + return "hi"; +>"hi" : "hi" + + }, + set(value: string) { +>set : (value: string) => void +>value : string + } + } + } +}); + +vue; +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } + +vue.x; +>vue.x : number +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>x : number + +vue.f("abc"); +>vue.f("abc") : number +>vue.f : (x: string) => number +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>f : (x: string) => number +>"abc" : "abc" + +vue.test; +>vue.test : number +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>test : number + +vue.hello; +>vue.hello : string +>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; } +>hello : string + diff --git a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts new file mode 100644 index 0000000000000..7358b47259c5a --- /dev/null +++ b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts @@ -0,0 +1,144 @@ +// @declaration: true +// @noImplicitAny: true +// @noImplicitThis: true +// @target: es5 + +// In methods of an object literal with no contextual type, 'this' has the type +// of the object literal. + +let obj1 = { + a: 1, + f() { + return this.a; + }, + b: "hello", + c: { + g() { + this.g(); + } + }, + get d() { + return this.a; + }, + get e() { + return this.b; + }, + set e(value) { + this.b = value; + } +}; + +// In methods of an object literal with a contextual type, 'this' has the +// contextual type. + +type Point = { + x: number; + y: number; + moveBy(dx: number, dy: number): void; +} + +let p1: Point = { + x: 10, + y: 20, + moveBy(dx, dy) { + this.x += dx; + this.y += dy; + } +}; + +declare function f1(p: Point): void; + +f1({ + x: 10, + y: 20, + moveBy(dx, dy) { + this.x += dx; + this.y += dy; + } +}); + +// In methods of an object literal with a contextual type that includes some +// ThisType, 'this' is of type T. + +type ObjectDescriptor = { + data?: D; + methods?: M & ThisType; // Type of 'this' in methods is D & M +} + +declare function makeObject(desc: ObjectDescriptor): D & M; + +let x1 = makeObject({ + data: { x: 0, y: 0 }, + methods: { + moveBy(dx: number, dy: number) { + this.x += dx; // Strongly typed this + this.y += dy; // Strongly typed this + } + } +}); + +// In methods contained in an object literal with a contextual type that includes +// some ThisType, 'this' is of type T. + +type ObjectDescriptor2 = ThisType & { + data?: D; + methods?: M; +} + +declare function makeObject2(desc: ObjectDescriptor): D & M; + +let x2 = makeObject2({ + data: { x: 0, y: 0 }, + methods: { + moveBy(dx: number, dy: number) { + this.x += dx; // Strongly typed this + this.y += dy; // Strongly typed this + } + } +}); + +// Proof of concept for typing of Vue.js + +type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; + +type Dictionary = { [x: string]: T } + +type Computed = { + get?(): T; + set?(value: T): void; +} + +type VueOptions = ThisType & { + data?: D | (() => D); + methods?: M; + computed?: Accessors

; +} + +declare const Vue: new (options: VueOptions) => D & M & P; + +let vue = new Vue({ + data: () => ({ x: 1, y: 2 }), + methods: { + f(x: string) { + return this.x; + } + }, + computed: { + test(): number { + return this.x; + }, + hello: { + get() { + return "hi"; + }, + set(value: string) { + } + } + } +}); + +vue; +vue.x; +vue.f("abc"); +vue.test; +vue.hello; From 993397b5ab291567f31bd437c81bc4c24a9d2a3d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 Feb 2017 08:54:38 -0800 Subject: [PATCH 18/26] Introduce CheckMode enum and getContextualMapper() function --- src/compiler/checker.ts | 208 ++++++++++++++++++++-------------------- src/compiler/types.ts | 3 +- 2 files changed, 107 insertions(+), 104 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff3a1079b189a..6e47b7a98083e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -433,6 +433,12 @@ namespace ts { ResolvedReturnType } + const enum CheckMode { + Normal = 0, // Normal type checking + SkipContextSensitive = 1, // Skip context sensitive function expressions + Inferential = 2, // Inferential typing + } + const builtinGlobals = createMap(); builtinGlobals.set(undefinedSymbol.name, undefinedSymbol); @@ -11543,7 +11549,7 @@ namespace ts { while (type) { const thisType = getThisTypeFromContextualType(type); if (thisType) { - return thisType; + return instantiateType(thisType, getContextualMapper(containingLiteral)); } if (literal.parent.kind !== SyntaxKind.PropertyAssignment) { break; @@ -11929,6 +11935,16 @@ namespace ts { return undefined; } + function getContextualMapper(node: Node) { + while (node) { + if (node.contextualMapper) { + return node.contextualMapper; + } + node = node.parent; + } + return identityMapper; + } + // If the given type is an object or union type, if that type has a single signature, and if // that signature is non-generic, return the signature. Otherwise return undefined. function getNonGenericSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { @@ -12019,31 +12035,12 @@ namespace ts { return result; } - /** - * Detect if the mapper implies an inference context. Specifically, there are 4 possible values - * for a mapper. Let's go through each one of them: - * - * 1. undefined - this means we are not doing inferential typing, but we may do contextual typing, - * which could cause us to assign a parameter a type - * 2. identityMapper - means we want to avoid assigning a parameter a type, whether or not we are in - * inferential typing (context is undefined for the identityMapper) - * 3. a mapper created by createInferenceMapper - we are doing inferential typing, we want to assign - * types to parameters and fix type parameters (context is defined) - * 4. an instantiation mapper created by createTypeMapper or createTypeEraser - this should never be - * passed as the contextual mapper when checking an expression (context is undefined for these) - * - * isInferentialContext is detecting if we are in case 3 - */ - function isInferentialContext(mapper: TypeMapper) { - return mapper && mapper.context; - } - - function checkSpreadExpression(node: SpreadElement, contextualMapper?: TypeMapper): Type { + function checkSpreadExpression(node: SpreadElement, checkMode?: CheckMode): Type { if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, ExternalEmitHelpers.SpreadIncludes); } - const arrayOrIterableType = checkExpression(node.expression, contextualMapper); + const arrayOrIterableType = checkExpression(node.expression, checkMode); return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterable*/ false); } @@ -12052,7 +12049,7 @@ namespace ts { (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.EqualsToken); } - function checkArrayLiteral(node: ArrayLiteralExpression, contextualMapper?: TypeMapper): Type { + function checkArrayLiteral(node: ArrayLiteralExpression, checkMode?: CheckMode): Type { const elements = node.elements; let hasSpreadElement = false; const elementTypes: Type[] = []; @@ -12071,7 +12068,7 @@ namespace ts { // get the contextual element type from it. So we do something similar to // getContextualTypeForElementExpression, which will crucially not error // if there is no index type / iterated type. - const restArrayType = checkExpression((e).expression, contextualMapper); + const restArrayType = checkExpression((e).expression, checkMode); const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) || getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterable*/ false, /*checkAssignability*/ false); if (restElementType) { @@ -12079,7 +12076,7 @@ namespace ts { } } else { - const type = checkExpressionForMutableLocation(e, contextualMapper); + const type = checkExpressionForMutableLocation(e, checkMode); elementTypes.push(type); } hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElement; @@ -12194,7 +12191,7 @@ namespace ts { return createIndexInfo(unionType, /*isReadonly*/ false); } - function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type { + function checkObjectLiteral(node: ObjectLiteralExpression, checkMode?: CheckMode): Type { const inDestructuringPattern = isAssignmentTarget(node); // Grammar checking checkGrammarObjectLiteralExpression(node, inDestructuringPattern); @@ -12221,14 +12218,14 @@ namespace ts { isObjectLiteralMethod(memberDecl)) { let type: Type; if (memberDecl.kind === SyntaxKind.PropertyAssignment) { - type = checkPropertyAssignment(memberDecl, contextualMapper); + type = checkPropertyAssignment(memberDecl, checkMode); } else if (memberDecl.kind === SyntaxKind.MethodDeclaration) { - type = checkObjectLiteralMethod(memberDecl, contextualMapper); + type = checkObjectLiteralMethod(memberDecl, checkMode); } else { Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment); - type = checkExpressionForMutableLocation((memberDecl).name, contextualMapper); + type = checkExpressionForMutableLocation((memberDecl).name, checkMode); } typeFlags |= type.flags; @@ -12434,7 +12431,7 @@ namespace ts { * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral, * which also calls getSpreadType. */ - function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean, contextualMapper?: TypeMapper) { + function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean, checkMode?: CheckMode) { const attributes = openingLikeElement.attributes; let attributesTable = createMap(); let spread: Type = emptyObjectType; @@ -12443,7 +12440,7 @@ namespace ts { const member = attributeDecl.symbol; if (isJsxAttribute(attributeDecl)) { const exprType = attributeDecl.initializer ? - checkExpression(attributeDecl.initializer, contextualMapper) : + checkExpression(attributeDecl.initializer, checkMode) : trueType; // is sugar for const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name); @@ -12514,8 +12511,8 @@ namespace ts { * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used) * @param node a JSXAttributes to be resolved of its type */ - function checkJsxAttributes(node: JsxAttributes, contextualMapper?: TypeMapper) { - return createJsxAttributesTypeFromAttributesProperty(node.parent as JsxOpeningLikeElement, /*filter*/ undefined, contextualMapper); + function checkJsxAttributes(node: JsxAttributes, checkMode?: CheckMode) { + return createJsxAttributesTypeFromAttributesProperty(node.parent as JsxOpeningLikeElement, /*filter*/ undefined, checkMode); } function getJsxType(name: string) { @@ -13013,9 +13010,9 @@ namespace ts { } } - function checkJsxExpression(node: JsxExpression, contextualMapper?: TypeMapper) { + function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) { if (node.expression) { - const type = checkExpression(node.expression, contextualMapper); + const type = checkExpression(node.expression, checkMode); if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) { error(node, Diagnostics.JSX_spread_child_must_be_an_array_type, node.toString(), typeToString(type)); } @@ -14877,9 +14874,9 @@ namespace ts { return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType; } - function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) { + function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper, checkMode: CheckMode) { const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0); - if (isInferentialContext(mapper)) { + if (checkMode === CheckMode.Inferential) { for (let i = 0; i < len; i++) { const declaration = signature.parameters[i].valueDeclaration; if (declaration.type) { @@ -14893,21 +14890,21 @@ namespace ts { if (!parameter) { signature.thisParameter = createSymbolWithType(context.thisParameter, undefined); } - assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper); + assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper, checkMode); } } for (let i = 0; i < len; i++) { const parameter = signature.parameters[i]; if (!(parameter.valueDeclaration).type) { const contextualParameterType = getTypeAtPosition(context, i); - assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); + assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode); } } if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) { const parameter = lastOrUndefined(signature.parameters); if (!(parameter.valueDeclaration).type) { const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters)); - assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); + assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode); } } } @@ -14927,7 +14924,7 @@ namespace ts { } } - function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper) { + function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper, checkMode: CheckMode) { const links = getSymbolLinks(parameter); if (!links.type) { links.type = instantiateType(contextualType, mapper); @@ -14939,7 +14936,7 @@ namespace ts { } assignBindingElementTypes(parameter.valueDeclaration); } - else if (isInferentialContext(mapper)) { + else if (checkMode === CheckMode.Inferential) { // Even if the parameter already has a type, it might be because it was given a type while // processing the function as an argument to a prior signature during overload resolution. // If this was the case, it may have caused some type parameters to be fixed. So here, @@ -15007,7 +15004,7 @@ namespace ts { return promiseType; } - function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type { + function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type { const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); if (!func.body) { return unknownType; @@ -15016,7 +15013,7 @@ namespace ts { const functionFlags = getFunctionFlags(func); let type: Type; if (func.body.kind !== SyntaxKind.Block) { - type = checkExpressionCached(func.body, contextualMapper); + type = checkExpressionCached(func.body, checkMode); if (functionFlags & FunctionFlags.Async) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the @@ -15028,7 +15025,7 @@ namespace ts { else { let types: Type[]; if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function - types = checkAndAggregateYieldOperandTypes(func, contextualMapper); + types = checkAndAggregateYieldOperandTypes(func, checkMode); if (types.length === 0) { const iterableIteratorAny = functionFlags & FunctionFlags.Async ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function @@ -15041,7 +15038,7 @@ namespace ts { } } else { - types = checkAndAggregateReturnExpressionTypes(func, contextualMapper); + types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (!types) { // For an async function, the return type will not be never, but rather a Promise for never. return functionFlags & FunctionFlags.Async @@ -15085,13 +15082,13 @@ namespace ts { : widenedType; // Generator function, AsyncGenerator function, or normal function } - function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] { + function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] { const aggregatedTypes: Type[] = []; const functionFlags = getFunctionFlags(func); forEachYieldExpression(func.body, yieldExpression => { const expr = yieldExpression.expression; if (expr) { - let type = checkExpressionCached(expr, contextualMapper); + let type = checkExpressionCached(expr, checkMode); if (yieldExpression.asteriskToken) { // A yield* expression effectively yields everything that its operand yields type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & FunctionFlags.Async) !== 0); @@ -15131,7 +15128,7 @@ namespace ts { return true; } - function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] { + function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] { const functionFlags = getFunctionFlags(func); const aggregatedTypes: Type[] = []; let hasReturnWithNoExpression = functionHasImplicitReturn(func); @@ -15139,7 +15136,7 @@ namespace ts { forEachReturnStatement(func.body, returnStatement => { const expr = returnStatement.expression; if (expr) { - let type = checkExpressionCached(expr, contextualMapper); + let type = checkExpressionCached(expr, checkMode); if (functionFlags & FunctionFlags.Async) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the @@ -15226,7 +15223,7 @@ namespace ts { } } - function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type { + function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, checkMode?: CheckMode): Type { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); // Grammar checking @@ -15236,7 +15233,7 @@ namespace ts { } // The identityMapper object is used to indicate that function expressions are wildcards - if (contextualMapper === identityMapper && isContextSensitive(node)) { + if (checkMode === CheckMode.SkipContextSensitive && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } @@ -15244,7 +15241,7 @@ namespace ts { const links = getNodeLinks(node); const type = getTypeOfSymbol(node.symbol); const contextSensitive = isContextSensitive(node); - const mightFixTypeParameters = contextSensitive && isInferentialContext(contextualMapper); + const mightFixTypeParameters = contextSensitive && checkMode === CheckMode.Inferential; // Check if function expression is contextually typed and assign parameter types if so. // See the comment in assignTypeToParameterAndFixTypeParameters to understand why we need to @@ -15260,10 +15257,10 @@ namespace ts { if (contextualSignature) { const signature = getSignaturesOfType(type, SignatureKind.Call)[0]; if (contextSensitive) { - assignContextualParameterTypes(signature, contextualSignature, contextualMapper || identityMapper); + assignContextualParameterTypes(signature, contextualSignature, getContextualMapper(node), checkMode); } if (mightFixTypeParameters || !node.type && !signature.resolvedReturnType) { - const returnType = getReturnTypeFromBody(node, contextualMapper); + const returnType = getReturnTypeFromBody(node, checkMode); if (!signature.resolvedReturnType) { signature.resolvedReturnType = returnType; } @@ -15639,7 +15636,7 @@ namespace ts { } } - function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type { + function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, checkMode?: CheckMode): Type { if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, ExternalEmitHelpers.Read); } @@ -15650,13 +15647,13 @@ namespace ts { const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterable*/ false) || unknownType; const elements = node.elements; for (let i = 0; i < elements.length; i++) { - checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, contextualMapper); + checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode); } return sourceType; } function checkArrayLiteralDestructuringElementAssignment(node: ArrayLiteralExpression, sourceType: Type, - elementIndex: number, elementType: Type, contextualMapper?: TypeMapper) { + elementIndex: number, elementType: Type, checkMode?: CheckMode) { const elements = node.elements; const element = elements[elementIndex]; if (element.kind !== SyntaxKind.OmittedExpression) { @@ -15668,7 +15665,7 @@ namespace ts { ? getTypeOfPropertyOfType(sourceType, propName) : elementType; if (type) { - return checkDestructuringAssignment(element, type, contextualMapper); + return checkDestructuringAssignment(element, type, checkMode); } else { // We still need to check element expression here because we may need to set appropriate flag on the expression @@ -15692,7 +15689,7 @@ namespace ts { error((restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer); } else { - return checkDestructuringAssignment(restExpression, createArrayType(elementType), contextualMapper); + return checkDestructuringAssignment(restExpression, createArrayType(elementType), checkMode); } } } @@ -15700,7 +15697,7 @@ namespace ts { return undefined; } - function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, contextualMapper?: TypeMapper): Type { + function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, checkMode?: CheckMode): Type { let target: Expression; if (exprOrAssignment.kind === SyntaxKind.ShorthandPropertyAssignment) { const prop = exprOrAssignment; @@ -15711,7 +15708,7 @@ namespace ts { !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & TypeFlags.Undefined)) { sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined); } - checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, contextualMapper); + checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode); } target = (exprOrAssignment).name; } @@ -15720,20 +15717,20 @@ namespace ts { } if (target.kind === SyntaxKind.BinaryExpression && (target).operatorToken.kind === SyntaxKind.EqualsToken) { - checkBinaryExpression(target, contextualMapper); + checkBinaryExpression(target, checkMode); target = (target).left; } if (target.kind === SyntaxKind.ObjectLiteralExpression) { return checkObjectLiteralAssignment(target, sourceType); } if (target.kind === SyntaxKind.ArrayLiteralExpression) { - return checkArrayLiteralAssignment(target, sourceType, contextualMapper); + return checkArrayLiteralAssignment(target, sourceType, checkMode); } - return checkReferenceAssignment(target, sourceType, contextualMapper); + return checkReferenceAssignment(target, sourceType, checkMode); } - function checkReferenceAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type { - const targetType = checkExpression(target, contextualMapper); + function checkReferenceAssignment(target: Expression, sourceType: Type, checkMode?: CheckMode): Type { + const targetType = checkExpression(target, checkMode); const error = target.parent.kind === SyntaxKind.SpreadAssignment ? Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access : Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access; @@ -15821,17 +15818,17 @@ namespace ts { getUnionType([type1, type2], /*subtypeReduction*/ true); } - function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) { - return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node); + function checkBinaryExpression(node: BinaryExpression, checkMode?: CheckMode) { + return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node); } - function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, contextualMapper?: TypeMapper, errorNode?: Node) { + function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, checkMode?: CheckMode, errorNode?: Node) { const operator = operatorToken.kind; if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) { - return checkDestructuringAssignment(left, checkExpression(right, contextualMapper), contextualMapper); + return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode); } - let leftType = checkExpression(left, contextualMapper); - let rightType = checkExpression(right, contextualMapper); + let leftType = checkExpression(left, checkMode); + let rightType = checkExpression(right, checkMode); switch (operator) { case SyntaxKind.AsteriskToken: case SyntaxKind.AsteriskAsteriskToken: @@ -16094,10 +16091,10 @@ namespace ts { return anyType; } - function checkConditionalExpression(node: ConditionalExpression, contextualMapper?: TypeMapper): Type { + function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type { checkExpression(node.condition); - const type1 = checkExpression(node.whenTrue, contextualMapper); - const type2 = checkExpression(node.whenFalse, contextualMapper); + const type1 = checkExpression(node.whenTrue, checkMode); + const type2 = checkExpression(node.whenFalse, checkMode); return getBestChoiceType(type1, type2); } @@ -16130,15 +16127,20 @@ namespace ts { return stringType; } - function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper?: TypeMapper): Type { + function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper): Type { const saveContextualType = node.contextualType; + const saveContextualMapper = node.contextualMapper; node.contextualType = contextualType; - const result = checkExpression(node, contextualMapper); + node.contextualMapper = contextualMapper; + const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive : + contextualMapper ? CheckMode.Inferential : CheckMode.Normal; + const result = checkExpression(node, checkMode); node.contextualType = saveContextualType; + node.contextualMapper = saveContextualMapper; return result; } - function checkExpressionCached(node: Expression, contextualMapper?: TypeMapper): Type { + function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { // When computing a type that we're going to cache, we need to ignore any ongoing control flow @@ -16146,7 +16148,7 @@ namespace ts { // to the top of the stack ensures all transient types are computed from a known point. const saveFlowLoopStart = flowLoopStart; flowLoopStart = flowLoopCount; - links.resolvedType = checkExpression(node, contextualMapper); + links.resolvedType = checkExpression(node, checkMode); flowLoopStart = saveFlowLoopStart; } return links.resolvedType; @@ -16181,12 +16183,12 @@ namespace ts { return false; } - function checkExpressionForMutableLocation(node: Expression, contextualMapper?: TypeMapper): Type { - const type = checkExpression(node, contextualMapper); + function checkExpressionForMutableLocation(node: Expression, checkMode?: CheckMode): Type { + const type = checkExpression(node, checkMode); return isTypeAssertion(node) || isLiteralContextualType(getContextualType(node)) ? type : getWidenedLiteralType(type); } - function checkPropertyAssignment(node: PropertyAssignment, contextualMapper?: TypeMapper): Type { + function checkPropertyAssignment(node: PropertyAssignment, checkMode?: CheckMode): Type { // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. @@ -16194,10 +16196,10 @@ namespace ts { checkComputedPropertyName(node.name); } - return checkExpressionForMutableLocation((node).initializer, contextualMapper); + return checkExpressionForMutableLocation((node).initializer, checkMode); } - function checkObjectLiteralMethod(node: MethodDeclaration, contextualMapper?: TypeMapper): Type { + function checkObjectLiteralMethod(node: MethodDeclaration, checkMode?: CheckMode): Type { // Grammar checking checkGrammarMethod(node); @@ -16208,19 +16210,19 @@ namespace ts { checkComputedPropertyName(node.name); } - const uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper); - return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, contextualMapper); + const uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode); + return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); } - function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration, type: Type, contextualMapper?: TypeMapper) { - if (isInferentialContext(contextualMapper)) { + function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration, type: Type, checkMode?: CheckMode) { + if (checkMode === CheckMode.Inferential) { const signature = getSingleCallSignature(type); if (signature && signature.typeParameters) { const contextualType = getApparentTypeOfContextualType(node); if (contextualType) { const contextualSignature = getSingleCallSignature(contextualType); if (contextualSignature && !contextualSignature.typeParameters) { - return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper)); + return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node))); } } } @@ -16254,14 +16256,14 @@ namespace ts { // object, it serves as an indicator that all contained function and arrow expressions should be considered to // have the wildcard function type; this form of type check is used during overload resolution to exclude // contextually typed function and arrow expressions in the initial phase. - function checkExpression(node: Expression | QualifiedName, contextualMapper?: TypeMapper): Type { + function checkExpression(node: Expression | QualifiedName, checkMode?: CheckMode): Type { let type: Type; if (node.kind === SyntaxKind.QualifiedName) { type = checkQualifiedName(node); } else { - const uninstantiatedType = checkExpressionWorker(node, contextualMapper); - type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, contextualMapper); + const uninstantiatedType = checkExpressionWorker(node, checkMode); + type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); } if (isConstEnumObjectType(type)) { @@ -16281,7 +16283,7 @@ namespace ts { return type; } - function checkExpressionWorker(node: Expression, contextualMapper: TypeMapper): Type { + function checkExpressionWorker(node: Expression, checkMode: CheckMode): Type { switch (node.kind) { case SyntaxKind.Identifier: return checkIdentifier(node); @@ -16303,9 +16305,9 @@ namespace ts { case SyntaxKind.RegularExpressionLiteral: return globalRegExpType; case SyntaxKind.ArrayLiteralExpression: - return checkArrayLiteral(node, contextualMapper); + return checkArrayLiteral(node, checkMode); case SyntaxKind.ObjectLiteralExpression: - return checkObjectLiteral(node, contextualMapper); + return checkObjectLiteral(node, checkMode); case SyntaxKind.PropertyAccessExpression: return checkPropertyAccessExpression(node); case SyntaxKind.ElementAccessExpression: @@ -16316,12 +16318,12 @@ namespace ts { case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); case SyntaxKind.ParenthesizedExpression: - return checkExpression((node).expression, contextualMapper); + return checkExpression((node).expression, checkMode); case SyntaxKind.ClassExpression: return checkClassExpression(node); case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - return checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper); + return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode); case SyntaxKind.TypeOfExpression: return checkTypeOfExpression(node); case SyntaxKind.TypeAssertionExpression: @@ -16342,23 +16344,23 @@ namespace ts { case SyntaxKind.PostfixUnaryExpression: return checkPostfixUnaryExpression(node); case SyntaxKind.BinaryExpression: - return checkBinaryExpression(node, contextualMapper); + return checkBinaryExpression(node, checkMode); case SyntaxKind.ConditionalExpression: - return checkConditionalExpression(node, contextualMapper); + return checkConditionalExpression(node, checkMode); case SyntaxKind.SpreadElement: - return checkSpreadExpression(node, contextualMapper); + return checkSpreadExpression(node, checkMode); case SyntaxKind.OmittedExpression: return undefinedWideningType; case SyntaxKind.YieldExpression: return checkYieldExpression(node); case SyntaxKind.JsxExpression: - return checkJsxExpression(node, contextualMapper); + return checkJsxExpression(node, checkMode); case SyntaxKind.JsxElement: return checkJsxElement(node); case SyntaxKind.JsxSelfClosingElement: return checkJsxSelfClosingElement(node); case SyntaxKind.JsxAttributes: - return checkJsxAttributes(node, contextualMapper); + return checkJsxAttributes(node, checkMode); case SyntaxKind.JsxOpeningElement: Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index de42d5d97450a..d42be483755d0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -522,6 +522,8 @@ /* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes) /* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding) /* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms) + /* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution + /* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type } export interface NodeArray extends Array, TextRange { @@ -960,7 +962,6 @@ export interface Expression extends Node { _expressionBrand: any; - contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution } export interface OmittedExpression extends Expression { From ff2cfd2af5008e086470ac244442559a6febbb2e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 Feb 2017 09:49:54 -0800 Subject: [PATCH 19/26] Update test --- .../thisType/thisTypeInObjectLiterals2.ts | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts index 7358b47259c5a..d476679aef1f7 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts @@ -1,4 +1,5 @@ // @declaration: true +// @strictNullChecks: true // @noImplicitAny: true // @noImplicitThis: true // @target: es5 @@ -34,15 +35,19 @@ let obj1 = { type Point = { x: number; y: number; - moveBy(dx: number, dy: number): void; + z?: number; + moveBy(dx: number, dy: number, dz?: number): void; } let p1: Point = { x: 10, y: 20, - moveBy(dx, dy) { + moveBy(dx, dy, dz) { this.x += dx; this.y += dy; + if (this.z && dz) { + this.z += dz; + } } }; @@ -51,9 +56,12 @@ declare function f1(p: Point): void; f1({ x: 10, y: 20, - moveBy(dx, dy) { + moveBy(dx, dy, dz) { this.x += dx; this.y += dy; + if (this.z && dz) { + this.z += dz; + } } }); @@ -97,6 +105,51 @@ let x2 = makeObject2({ } }); +// Check pattern similar to Object.defineProperty and Object.defineProperties + +type PropDesc = { + value?: T; + get?(): T; + set?(value: T): void; +} + +type PropDescMap = { + [K in keyof T]: PropDesc; +} + +declare function defineProp(obj: T, name: K, desc: PropDesc & ThisType): T & Record; + +declare function defineProps(obj: T, descs: PropDescMap & ThisType): T & U; + +let p10 = defineProp(p1, "foo", { value: 42 }); +p10.foo = p10.foo + 1; + +let p11 = defineProp(p1, "bar", { + get() { + return this.x; + }, + set(value: number) { + this.x = value; + } +}); +p11.bar = p11.bar + 1; + +let p12 = defineProps(p1, { + foo: { + value: 42 + }, + bar: { + get(): number { + return this.x; + }, + set(value: number) { + this.x = value; + } + } +}); +p12.foo = p12.foo + 1; +p12.bar = p12.bar + 1; + // Proof of concept for typing of Vue.js type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; From c87c124831856bd912d851a0505bd706e39022cb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 Feb 2017 09:50:02 -0800 Subject: [PATCH 20/26] Accept new baselines --- .../reference/thisTypeInObjectLiterals2.js | 113 +++- .../thisTypeInObjectLiterals2.symbols | 532 ++++++++++++------ .../reference/thisTypeInObjectLiterals2.types | 262 ++++++++- 3 files changed, 715 insertions(+), 192 deletions(-) diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.js b/tests/baselines/reference/thisTypeInObjectLiterals2.js index 08f02b6c5afda..88cbd2555f6d3 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.js +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.js @@ -31,15 +31,19 @@ let obj1 = { type Point = { x: number; y: number; - moveBy(dx: number, dy: number): void; + z?: number; + moveBy(dx: number, dy: number, dz?: number): void; } let p1: Point = { x: 10, y: 20, - moveBy(dx, dy) { + moveBy(dx, dy, dz) { this.x += dx; this.y += dy; + if (this.z && dz) { + this.z += dz; + } } }; @@ -48,9 +52,12 @@ declare function f1(p: Point): void; f1({ x: 10, y: 20, - moveBy(dx, dy) { + moveBy(dx, dy, dz) { this.x += dx; this.y += dy; + if (this.z && dz) { + this.z += dz; + } } }); @@ -94,6 +101,51 @@ let x2 = makeObject2({ } }); +// Check pattern similar to Object.defineProperty and Object.defineProperties + +type PropDesc = { + value?: T; + get?(): T; + set?(value: T): void; +} + +type PropDescMap = { + [K in keyof T]: PropDesc; +} + +declare function defineProp(obj: T, name: K, desc: PropDesc & ThisType): T & Record; + +declare function defineProps(obj: T, descs: PropDescMap & ThisType): T & U; + +let p10 = defineProp(p1, "foo", { value: 42 }); +p10.foo = p10.foo + 1; + +let p11 = defineProp(p1, "bar", { + get() { + return this.x; + }, + set(value: number) { + this.x = value; + } +}); +p11.bar = p11.bar + 1; + +let p12 = defineProps(p1, { + foo: { + value: 42 + }, + bar: { + get(): number { + return this.x; + }, + set(value: number) { + this.x = value; + } + } +}); +p12.foo = p12.foo + 1; +p12.bar = p12.bar + 1; + // Proof of concept for typing of Vue.js type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; @@ -168,17 +220,23 @@ var obj1 = { var p1 = { x: 10, y: 20, - moveBy: function (dx, dy) { + moveBy: function (dx, dy, dz) { this.x += dx; this.y += dy; + if (this.z && dz) { + this.z += dz; + } } }; f1({ x: 10, y: 20, - moveBy: function (dx, dy) { + moveBy: function (dx, dy, dz) { this.x += dx; this.y += dy; + if (this.z && dz) { + this.z += dz; + } } }); var x1 = makeObject({ @@ -199,6 +257,32 @@ var x2 = makeObject2({ } } }); +var p10 = defineProp(p1, "foo", { value: 42 }); +p10.foo = p10.foo + 1; +var p11 = defineProp(p1, "bar", { + get: function () { + return this.x; + }, + set: function (value) { + this.x = value; + } +}); +p11.bar = p11.bar + 1; +var p12 = defineProps(p1, { + foo: { + value: 42 + }, + bar: { + get: function () { + return this.x; + }, + set: function (value) { + this.x = value; + } + } +}); +p12.foo = p12.foo + 1; +p12.bar = p12.bar + 1; var vue = new Vue({ data: function () { return ({ x: 1, y: 2 }); }, methods: { @@ -240,7 +324,8 @@ declare let obj1: { declare type Point = { x: number; y: number; - moveBy(dx: number, dy: number): void; + z?: number; + moveBy(dx: number, dy: number, dz?: number): void; }; declare let p1: Point; declare function f1(p: Point): void; @@ -266,6 +351,22 @@ declare let x2: { } & { moveBy(dx: number, dy: number): void; }; +declare type PropDesc = { + value?: T; + get?(): T; + set?(value: T): void; +}; +declare type PropDescMap = { + [K in keyof T]: PropDesc; +}; +declare function defineProp(obj: T, name: K, desc: PropDesc & ThisType): T & Record; +declare function defineProps(obj: T, descs: PropDescMap & ThisType): T & U; +declare let p10: Point & Record<"foo", number>; +declare let p11: Point & Record<"bar", number>; +declare let p12: Point & { + foo: number; + bar: number; +}; declare type Accessors = { [K in keyof T]: (() => T[K]) | Computed; }; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.symbols b/tests/baselines/reference/thisTypeInObjectLiterals2.symbols index ef72c320cce23..e7412ab487f9f 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.symbols +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.symbols @@ -75,71 +75,103 @@ type Point = { y: number; >y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) - moveBy(dx: number, dy: number): void; ->moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 32, 11)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 32, 22)) + z?: number; +>z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) + + moveBy(dx: number, dy: number, dz?: number): void; +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 32, 15)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 33, 11)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 33, 22)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 33, 34)) } let p1: Point = { ->p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 35, 3)) +>p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 36, 3)) >Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2)) x: 10, ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 35, 17)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 36, 17)) y: 20, ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 36, 10)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 37, 10)) - moveBy(dx, dy) { ->moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 37, 10)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 38, 11)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 38, 14)) + moveBy(dx, dy, dz) { +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 38, 10)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 39, 11)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 39, 14)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 39, 18)) this.x += dx; >this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) >this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) >x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 38, 11)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 39, 11)) this.y += dy; >this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) >this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) >y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 38, 14)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 39, 14)) + + if (this.z && dz) { +>this.z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 39, 18)) + + this.z += dz; +>this.z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 39, 18)) + } } }; declare function f1(p: Point): void; ->f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 42, 2)) ->p : Symbol(p, Decl(thisTypeInObjectLiterals2.ts, 44, 20)) +>f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 46, 2)) +>p : Symbol(p, Decl(thisTypeInObjectLiterals2.ts, 48, 20)) >Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2)) f1({ ->f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 42, 2)) +>f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 46, 2)) x: 10, ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 46, 4)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 50, 4)) y: 20, ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 47, 10)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 51, 10)) - moveBy(dx, dy) { ->moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 48, 10)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 49, 11)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 49, 14)) + moveBy(dx, dy, dz) { +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 52, 10)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 53, 11)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 53, 14)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 53, 18)) this.x += dx; >this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) >this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) >x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 49, 11)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 53, 11)) this.y += dy; >this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) >this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) >y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 49, 14)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 53, 14)) + + if (this.z && dz) { +>this.z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 53, 18)) + + this.z += dz; +>this.z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>z : Symbol(z, Decl(thisTypeInObjectLiterals2.ts, 31, 14)) +>dz : Symbol(dz, Decl(thisTypeInObjectLiterals2.ts, 53, 18)) + } } }); @@ -147,59 +179,59 @@ f1({ // ThisType, 'this' is of type T. type ObjectDescriptor = { ->ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24)) +>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 60, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 65, 22)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 65, 24)) data?: D; ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 58, 31)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 65, 31)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 65, 22)) methods?: M & ThisType; // Type of 'this' in methods is D & M ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 59, 13)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 66, 13)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 65, 24)) >ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 65, 22)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 65, 24)) } declare function makeObject(desc: ObjectDescriptor): D & M; ->makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 61, 1)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30)) ->desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 63, 34)) ->ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30)) +>makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 68, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 70, 28)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 70, 30)) +>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 70, 34)) +>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 60, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 70, 28)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 70, 30)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 70, 28)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 70, 30)) let x1 = makeObject({ ->x1 : Symbol(x1, Decl(thisTypeInObjectLiterals2.ts, 65, 3)) ->makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 61, 1)) +>x1 : Symbol(x1, Decl(thisTypeInObjectLiterals2.ts, 72, 3)) +>makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 68, 1)) data: { x: 0, y: 0 }, ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 65, 21)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11)) ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 72, 21)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 73, 11)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 73, 17)) methods: { ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 66, 25)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 73, 25)) moveBy(dx: number, dy: number) { ->moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 67, 14)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 68, 15)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 68, 26)) +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 74, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 75, 15)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 75, 26)) this.x += dx; // Strongly typed this ->this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 68, 15)) +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 73, 11)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 73, 11)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 75, 15)) this.y += dy; // Strongly typed this ->this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17)) ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 68, 26)) +>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 73, 17)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 73, 17)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 75, 26)) } } }); @@ -208,203 +240,367 @@ let x1 = makeObject({ // some ThisType, 'this' is of type T. type ObjectDescriptor2 = ThisType & { ->ObjectDescriptor2 : Symbol(ObjectDescriptor2, Decl(thisTypeInObjectLiterals2.ts, 73, 3)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25)) +>ObjectDescriptor2 : Symbol(ObjectDescriptor2, Decl(thisTypeInObjectLiterals2.ts, 80, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 85, 23)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 85, 25)) >ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 85, 23)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 85, 25)) data?: D; ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 78, 50)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 85, 50)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 85, 23)) methods?: M; ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 79, 13)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 86, 13)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 85, 25)) } declare function makeObject2(desc: ObjectDescriptor): D & M; ->makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 81, 1)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31)) ->desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 83, 35)) ->ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31)) +>makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 88, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 90, 29)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 90, 31)) +>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 90, 35)) +>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 60, 3)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 90, 29)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 90, 31)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 90, 29)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 90, 31)) let x2 = makeObject2({ ->x2 : Symbol(x2, Decl(thisTypeInObjectLiterals2.ts, 85, 3)) ->makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 81, 1)) +>x2 : Symbol(x2, Decl(thisTypeInObjectLiterals2.ts, 92, 3)) +>makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 88, 1)) data: { x: 0, y: 0 }, ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 85, 22)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11)) ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 92, 22)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 93, 11)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 93, 17)) methods: { ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 86, 25)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 93, 25)) moveBy(dx: number, dy: number) { ->moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 87, 14)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 88, 15)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 88, 26)) +>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 94, 14)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 95, 15)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 95, 26)) this.x += dx; // Strongly typed this ->this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11)) ->dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 88, 15)) +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 93, 11)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 93, 11)) +>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 95, 15)) this.y += dy; // Strongly typed this ->this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17)) ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17)) ->dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 88, 26)) +>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 93, 17)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 93, 17)) +>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 95, 26)) + } + } +}); + +// Check pattern similar to Object.defineProperty and Object.defineProperties + +type PropDesc = { +>PropDesc : Symbol(PropDesc, Decl(thisTypeInObjectLiterals2.ts, 100, 3)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 104, 14)) + + value?: T; +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 104, 20)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 104, 14)) + + get?(): T; +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 105, 14)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 104, 14)) + + set?(value: T): void; +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 106, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 107, 9)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 104, 14)) +} + +type PropDescMap = { +>PropDescMap : Symbol(PropDescMap, Decl(thisTypeInObjectLiterals2.ts, 108, 1)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 110, 17)) + + [K in keyof T]: PropDesc; +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 111, 5)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 110, 17)) +>PropDesc : Symbol(PropDesc, Decl(thisTypeInObjectLiterals2.ts, 100, 3)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 110, 17)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 111, 5)) +} + +declare function defineProp(obj: T, name: K, desc: PropDesc & ThisType): T & Record; +>defineProp : Symbol(defineProp, Decl(thisTypeInObjectLiterals2.ts, 112, 1)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 114, 28)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 114, 30)) +>U : Symbol(U, Decl(thisTypeInObjectLiterals2.ts, 114, 48)) +>obj : Symbol(obj, Decl(thisTypeInObjectLiterals2.ts, 114, 52)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 114, 28)) +>name : Symbol(name, Decl(thisTypeInObjectLiterals2.ts, 114, 59)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 114, 30)) +>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 114, 68)) +>PropDesc : Symbol(PropDesc, Decl(thisTypeInObjectLiterals2.ts, 100, 3)) +>U : Symbol(U, Decl(thisTypeInObjectLiterals2.ts, 114, 48)) +>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 114, 28)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 114, 28)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 114, 30)) +>U : Symbol(U, Decl(thisTypeInObjectLiterals2.ts, 114, 48)) + +declare function defineProps(obj: T, descs: PropDescMap & ThisType): T & U; +>defineProps : Symbol(defineProps, Decl(thisTypeInObjectLiterals2.ts, 114, 120)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 116, 29)) +>U : Symbol(U, Decl(thisTypeInObjectLiterals2.ts, 116, 31)) +>obj : Symbol(obj, Decl(thisTypeInObjectLiterals2.ts, 116, 35)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 116, 29)) +>descs : Symbol(descs, Decl(thisTypeInObjectLiterals2.ts, 116, 42)) +>PropDescMap : Symbol(PropDescMap, Decl(thisTypeInObjectLiterals2.ts, 108, 1)) +>U : Symbol(U, Decl(thisTypeInObjectLiterals2.ts, 116, 31)) +>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 116, 29)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 116, 29)) +>U : Symbol(U, Decl(thisTypeInObjectLiterals2.ts, 116, 31)) + +let p10 = defineProp(p1, "foo", { value: 42 }); +>p10 : Symbol(p10, Decl(thisTypeInObjectLiterals2.ts, 118, 3)) +>defineProp : Symbol(defineProp, Decl(thisTypeInObjectLiterals2.ts, 112, 1)) +>p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 36, 3)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 118, 33)) + +p10.foo = p10.foo + 1; +>p10.foo : Symbol(foo) +>p10 : Symbol(p10, Decl(thisTypeInObjectLiterals2.ts, 118, 3)) +>foo : Symbol(foo) +>p10.foo : Symbol(foo) +>p10 : Symbol(p10, Decl(thisTypeInObjectLiterals2.ts, 118, 3)) +>foo : Symbol(foo) + +let p11 = defineProp(p1, "bar", { +>p11 : Symbol(p11, Decl(thisTypeInObjectLiterals2.ts, 121, 3)) +>defineProp : Symbol(defineProp, Decl(thisTypeInObjectLiterals2.ts, 112, 1)) +>p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 36, 3)) + + get() { +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 121, 33)) + + return this.x; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) + + }, + set(value: number) { +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 124, 6)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 125, 8)) + + this.x = value; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 125, 8)) + } +}); +p11.bar = p11.bar + 1; +>p11.bar : Symbol(bar) +>p11 : Symbol(p11, Decl(thisTypeInObjectLiterals2.ts, 121, 3)) +>bar : Symbol(bar) +>p11.bar : Symbol(bar) +>p11 : Symbol(p11, Decl(thisTypeInObjectLiterals2.ts, 121, 3)) +>bar : Symbol(bar) + +let p12 = defineProps(p1, { +>p12 : Symbol(p12, Decl(thisTypeInObjectLiterals2.ts, 131, 3)) +>defineProps : Symbol(defineProps, Decl(thisTypeInObjectLiterals2.ts, 114, 120)) +>p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 36, 3)) + + foo: { +>foo : Symbol(foo, Decl(thisTypeInObjectLiterals2.ts, 131, 27)) + + value: 42 +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 132, 10)) + + }, + bar: { +>bar : Symbol(bar, Decl(thisTypeInObjectLiterals2.ts, 134, 6)) + + get(): number { +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 135, 10)) + + return this.x; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) + + }, + set(value: number) { +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 138, 10)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 139, 12)) + + this.x = value; +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 139, 12)) } } }); +p12.foo = p12.foo + 1; +>p12.foo : Symbol(foo, Decl(thisTypeInObjectLiterals2.ts, 131, 27)) +>p12 : Symbol(p12, Decl(thisTypeInObjectLiterals2.ts, 131, 3)) +>foo : Symbol(foo, Decl(thisTypeInObjectLiterals2.ts, 131, 27)) +>p12.foo : Symbol(foo, Decl(thisTypeInObjectLiterals2.ts, 131, 27)) +>p12 : Symbol(p12, Decl(thisTypeInObjectLiterals2.ts, 131, 3)) +>foo : Symbol(foo, Decl(thisTypeInObjectLiterals2.ts, 131, 27)) + +p12.bar = p12.bar + 1; +>p12.bar : Symbol(bar, Decl(thisTypeInObjectLiterals2.ts, 134, 6)) +>p12 : Symbol(p12, Decl(thisTypeInObjectLiterals2.ts, 131, 3)) +>bar : Symbol(bar, Decl(thisTypeInObjectLiterals2.ts, 134, 6)) +>p12.bar : Symbol(bar, Decl(thisTypeInObjectLiterals2.ts, 134, 6)) +>p12 : Symbol(p12, Decl(thisTypeInObjectLiterals2.ts, 131, 3)) +>bar : Symbol(bar, Decl(thisTypeInObjectLiterals2.ts, 134, 6)) // Proof of concept for typing of Vue.js type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; ->Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 93, 3)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) ->K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) ->K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23)) ->Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 99, 39)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15)) ->K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23)) +>Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 145, 22)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 149, 15)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 149, 23)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 149, 15)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 149, 15)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 149, 23)) +>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 151, 39)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 149, 15)) +>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 149, 23)) type Dictionary = { [x: string]: T } ->Dictionary : Symbol(Dictionary, Decl(thisTypeInObjectLiterals2.ts, 97, 70)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 99, 16)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 99, 24)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 99, 16)) +>Dictionary : Symbol(Dictionary, Decl(thisTypeInObjectLiterals2.ts, 149, 70)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 151, 16)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 151, 24)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 151, 16)) type Computed = { ->Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 99, 39)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14)) +>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 151, 39)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 153, 14)) get?(): T; ->get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 101, 20)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14)) +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 153, 20)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 153, 14)) set?(value: T): void; ->set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 102, 14)) ->value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 103, 9)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14)) +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 154, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 155, 9)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 153, 14)) } type VueOptions = ThisType & { ->VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 104, 1)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21)) +>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 156, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 158, 16)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 158, 18)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 158, 21)) >ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 158, 16)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 158, 18)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 158, 21)) data?: D | (() => D); ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 106, 50)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 158, 50)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 158, 16)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 158, 16)) methods?: M; ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 107, 25)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 159, 25)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 158, 18)) computed?: Accessors

; ->computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 108, 16)) ->Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 93, 3)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21)) +>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 160, 16)) +>Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 145, 22)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 158, 21)) } declare const Vue: new (options: VueOptions) => D & M & P; ->Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 112, 13)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29)) ->options : Symbol(options, Decl(thisTypeInObjectLiterals2.ts, 112, 33)) ->VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 104, 1)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29)) +>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 164, 13)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 164, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 164, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 164, 29)) +>options : Symbol(options, Decl(thisTypeInObjectLiterals2.ts, 164, 33)) +>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 156, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 164, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 164, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 164, 29)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 164, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 164, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 164, 29)) let vue = new Vue({ ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) ->Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 112, 13)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 166, 3)) +>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 164, 13)) data: () => ({ x: 1, y: 2 }), ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 114, 19)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 115, 24)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 166, 19)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 167, 24)) methods: { ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 115, 33)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 167, 33)) f(x: string) { ->f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 117, 10)) +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 168, 14)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 169, 10)) return this.x; ->this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) } }, computed: { ->computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 120, 6)) +>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 172, 6)) test(): number { ->test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15)) +>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 173, 15)) return this.x; ->this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) }, hello: { ->hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10)) +>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 176, 10)) get() { ->get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 125, 16)) +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 177, 16)) return "hi"; }, set(value: string) { ->set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 128, 14)) ->value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 129, 16)) +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 180, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 181, 16)) } } } }); vue; ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 166, 3)) vue.x; ->vue.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18)) +>vue.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 166, 3)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 167, 18)) vue.f("abc"); ->vue.f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) ->f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14)) +>vue.f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 168, 14)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 166, 3)) +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 168, 14)) vue.test; ->vue.test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) ->test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15)) +>vue.test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 173, 15)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 166, 3)) +>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 173, 15)) vue.hello; ->vue.hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3)) ->hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10)) +>vue.hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 176, 10)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 166, 3)) +>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 176, 10)) diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.types b/tests/baselines/reference/thisTypeInObjectLiterals2.types index 39fd922f6179b..cc41be6b8c6a9 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.types @@ -81,16 +81,20 @@ type Point = { y: number; >y : number - moveBy(dx: number, dy: number): void; ->moveBy : (dx: number, dy: number) => void + z?: number; +>z : number | undefined + + moveBy(dx: number, dy: number, dz?: number): void; +>moveBy : (dx: number, dy: number, dz?: number | undefined) => void >dx : number >dy : number +>dz : number | undefined } let p1: Point = { >p1 : Point >Point : Point ->{ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }} : { x: number; y: number; moveBy(dx: number, dy: number): void; } +>{ x: 10, y: 20, moveBy(dx, dy, dz) { this.x += dx; this.y += dy; if (this.z && dz) { this.z += dz; } }} : { x: number; y: number; moveBy(dx: number, dy: number, dz: number | undefined): void; } x: 10, >x : number @@ -100,10 +104,11 @@ let p1: Point = { >y : number >20 : 20 - moveBy(dx, dy) { ->moveBy : (dx: number, dy: number) => void + moveBy(dx, dy, dz) { +>moveBy : (dx: number, dy: number, dz: number | undefined) => void >dx : number >dy : number +>dz : number | undefined this.x += dx; >this.x += dx : number @@ -118,6 +123,21 @@ let p1: Point = { >this : Point >y : number >dy : number + + if (this.z && dz) { +>this.z && dz : number | undefined +>this.z : number | undefined +>this : Point +>z : number | undefined +>dz : number | undefined + + this.z += dz; +>this.z += dz : number +>this.z : number +>this : Point +>z : number +>dz : number + } } }; @@ -127,9 +147,9 @@ declare function f1(p: Point): void; >Point : Point f1({ ->f1({ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }}) : void +>f1({ x: 10, y: 20, moveBy(dx, dy, dz) { this.x += dx; this.y += dy; if (this.z && dz) { this.z += dz; } }}) : void >f1 : (p: Point) => void ->{ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }} : { x: number; y: number; moveBy(dx: number, dy: number): void; } +>{ x: 10, y: 20, moveBy(dx, dy, dz) { this.x += dx; this.y += dy; if (this.z && dz) { this.z += dz; } }} : { x: number; y: number; moveBy(dx: number, dy: number, dz: number | undefined): void; } x: 10, >x : number @@ -139,10 +159,11 @@ f1({ >y : number >20 : 20 - moveBy(dx, dy) { ->moveBy : (dx: number, dy: number) => void + moveBy(dx, dy, dz) { +>moveBy : (dx: number, dy: number, dz: number | undefined) => void >dx : number >dy : number +>dz : number | undefined this.x += dx; >this.x += dx : number @@ -157,6 +178,21 @@ f1({ >this : Point >y : number >dy : number + + if (this.z && dz) { +>this.z && dz : number | undefined +>this.z : number | undefined +>this : Point +>z : number | undefined +>dz : number | undefined + + this.z += dz; +>this.z += dz : number +>this.z : number +>this : Point +>z : number +>dz : number + } } }); @@ -169,11 +205,11 @@ type ObjectDescriptor = { >M : M data?: D; ->data : D +>data : D | undefined >D : D methods?: M & ThisType; // Type of 'this' in methods is D & M ->methods : M & ThisType +>methods : (M & ThisType) | undefined >M : M >ThisType : ThisType >D : D @@ -243,11 +279,11 @@ type ObjectDescriptor2 = ThisType & { >M : M data?: D; ->data : D +>data : D | undefined >D : D methods?: M; ->methods : M +>methods : M | undefined >M : M } @@ -302,6 +338,196 @@ let x2 = makeObject2({ } }); +// Check pattern similar to Object.defineProperty and Object.defineProperties + +type PropDesc = { +>PropDesc : PropDesc +>T : T + + value?: T; +>value : T | undefined +>T : T + + get?(): T; +>get : (() => T) | undefined +>T : T + + set?(value: T): void; +>set : ((value: T) => void) | undefined +>value : T +>T : T +} + +type PropDescMap = { +>PropDescMap : PropDescMap +>T : T + + [K in keyof T]: PropDesc; +>K : K +>T : T +>PropDesc : PropDesc +>T : T +>K : K +} + +declare function defineProp(obj: T, name: K, desc: PropDesc & ThisType): T & Record; +>defineProp : (obj: T, name: K, desc: PropDesc & ThisType) => T & Record +>T : T +>K : K +>U : U +>obj : T +>T : T +>name : K +>K : K +>desc : PropDesc & ThisType +>PropDesc : PropDesc +>U : U +>ThisType : ThisType +>T : T +>T : T +>Record : Record +>K : K +>U : U + +declare function defineProps(obj: T, descs: PropDescMap & ThisType): T & U; +>defineProps : (obj: T, descs: PropDescMap & ThisType) => T & U +>T : T +>U : U +>obj : T +>T : T +>descs : PropDescMap & ThisType +>PropDescMap : PropDescMap +>U : U +>ThisType : ThisType +>T : T +>T : T +>U : U + +let p10 = defineProp(p1, "foo", { value: 42 }); +>p10 : Point & Record<"foo", number> +>defineProp(p1, "foo", { value: 42 }) : Point & Record<"foo", number> +>defineProp : (obj: T, name: K, desc: PropDesc & ThisType) => T & Record +>p1 : Point +>"foo" : "foo" +>{ value: 42 } : { value: number; } +>value : number +>42 : 42 + +p10.foo = p10.foo + 1; +>p10.foo = p10.foo + 1 : number +>p10.foo : number +>p10 : Point & Record<"foo", number> +>foo : number +>p10.foo + 1 : number +>p10.foo : number +>p10 : Point & Record<"foo", number> +>foo : number +>1 : 1 + +let p11 = defineProp(p1, "bar", { +>p11 : Point & Record<"bar", number> +>defineProp(p1, "bar", { get() { return this.x; }, set(value: number) { this.x = value; }}) : Point & Record<"bar", number> +>defineProp : (obj: T, name: K, desc: PropDesc & ThisType) => T & Record +>p1 : Point +>"bar" : "bar" +>{ get() { return this.x; }, set(value: number) { this.x = value; }} : { get(): number; set(value: number): void; } + + get() { +>get : () => number + + return this.x; +>this.x : number +>this : Point +>x : number + + }, + set(value: number) { +>set : (value: number) => void +>value : number + + this.x = value; +>this.x = value : number +>this.x : number +>this : Point +>x : number +>value : number + } +}); +p11.bar = p11.bar + 1; +>p11.bar = p11.bar + 1 : number +>p11.bar : number +>p11 : Point & Record<"bar", number> +>bar : number +>p11.bar + 1 : number +>p11.bar : number +>p11 : Point & Record<"bar", number> +>bar : number +>1 : 1 + +let p12 = defineProps(p1, { +>p12 : Point & { foo: number; bar: number; } +>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: number; bar: number; } +>defineProps : (obj: T, descs: PropDescMap & ThisType) => T & U +>p1 : Point +>{ foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }} : { foo: { value: number; }; bar: { get(): number; set(value: number): void; }; } + + foo: { +>foo : { value: number; } +>{ value: 42 } : { value: number; } + + value: 42 +>value : number +>42 : 42 + + }, + bar: { +>bar : { get(): number; set(value: number): void; } +>{ get(): number { return this.x; }, set(value: number) { this.x = value; } } : { get(): number; set(value: number): void; } + + get(): number { +>get : () => number + + return this.x; +>this.x : number +>this : Point +>x : number + + }, + set(value: number) { +>set : (value: number) => void +>value : number + + this.x = value; +>this.x = value : number +>this.x : number +>this : Point +>x : number +>value : number + } + } +}); +p12.foo = p12.foo + 1; +>p12.foo = p12.foo + 1 : number +>p12.foo : number +>p12 : Point & { foo: number; bar: number; } +>foo : number +>p12.foo + 1 : number +>p12.foo : number +>p12 : Point & { foo: number; bar: number; } +>foo : number +>1 : 1 + +p12.bar = p12.bar + 1; +>p12.bar = p12.bar + 1 : number +>p12.bar : number +>p12 : Point & { foo: number; bar: number; } +>bar : number +>p12.bar + 1 : number +>p12.bar : number +>p12 : Point & { foo: number; bar: number; } +>bar : number +>1 : 1 + // Proof of concept for typing of Vue.js type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; @@ -326,11 +552,11 @@ type Computed = { >T : T get?(): T; ->get : () => T +>get : (() => T) | undefined >T : T set?(value: T): void; ->set : (value: T) => void +>set : ((value: T) => void) | undefined >value : T >T : T } @@ -346,16 +572,16 @@ type VueOptions = ThisType & { >P : P data?: D | (() => D); ->data : D | (() => D) +>data : D | (() => D) | undefined >D : D >D : D methods?: M; ->methods : M +>methods : M | undefined >M : M computed?: Accessors

; ->computed : Accessors

+>computed : Accessors

| undefined >Accessors : Accessors >P : P } From 21c43009a667103d3818c6b3a03bcde1ca6654d6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 Feb 2017 16:09:24 -0800 Subject: [PATCH 21/26] Enable new behavior only in --noImplicitThis mode --- src/compiler/checker.ts | 58 +++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a5c0f1819cb56..6fb2e497a8db4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11570,36 +11570,38 @@ namespace ts { } } } - const containingLiteral = getContainingObjectLiteral(func); - if (containingLiteral) { - // We have an object literal method. Check if the containing object literal has a contextual type - // that includes a ThisType. If so, T is the contextual type for 'this'. We continue looking in - // any directly enclosing object literals. - const contextualType = getApparentTypeOfContextualType(containingLiteral); - let literal = containingLiteral; - let type = contextualType; - while (type) { - const thisType = getThisTypeFromContextualType(type); - if (thisType) { - return instantiateType(thisType, getContextualMapper(containingLiteral)); - } - if (literal.parent.kind !== SyntaxKind.PropertyAssignment) { - break; + if (compilerOptions.noImplicitThis) { + const containingLiteral = getContainingObjectLiteral(func); + if (containingLiteral) { + // We have an object literal method. Check if the containing object literal has a contextual type + // that includes a ThisType. If so, T is the contextual type for 'this'. We continue looking in + // any directly enclosing object literals. + const contextualType = getApparentTypeOfContextualType(containingLiteral); + let literal = containingLiteral; + let type = contextualType; + while (type) { + const thisType = getThisTypeFromContextualType(type); + if (thisType) { + return instantiateType(thisType, getContextualMapper(containingLiteral)); + } + if (literal.parent.kind !== SyntaxKind.PropertyAssignment) { + break; + } + literal = literal.parent.parent; + type = getApparentTypeOfContextualType(literal); } - literal = literal.parent.parent; - type = getApparentTypeOfContextualType(literal); + // There was no contextual ThisType for the containing object literal, so the contextual type + // for 'this' is the contextual type for the containing object literal or the type of the object + // literal itself. + return contextualType || checkExpressionCached(containingLiteral); } - // There was no contextual ThisType for the containing object literal, so the contextual type - // for 'this' is the contextual type for the containing object literal or the type of the object - // literal itself. - return contextualType || checkExpressionCached(containingLiteral); - } - // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the - // contextual type for 'this' is 'obj'. - if (func.parent.kind === SyntaxKind.BinaryExpression && (func.parent).operatorToken.kind === SyntaxKind.EqualsToken) { - const target = (func.parent).left; - if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) { - return checkExpressionCached((target).expression); + // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the + // contextual type for 'this' is 'obj'. + if (func.parent.kind === SyntaxKind.BinaryExpression && (func.parent).operatorToken.kind === SyntaxKind.EqualsToken) { + const target = (func.parent).left; + if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) { + return checkExpressionCached((target).expression); + } } } return undefined; From 25738a8e411478896c65d983fa48840bb39db496 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 Feb 2017 16:09:42 -0800 Subject: [PATCH 22/26] Update tests --- tests/cases/compiler/selfInLambdas.ts | 3 +++ tests/cases/compiler/thisBinding2.ts | 3 +++ .../conformance/types/thisType/looseThisTypeInFunctions.ts | 3 +++ tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts | 3 +++ .../conformance/types/thisType/thisTypeInObjectLiterals.ts | 3 +++ 5 files changed, 15 insertions(+) diff --git a/tests/cases/compiler/selfInLambdas.ts b/tests/cases/compiler/selfInLambdas.ts index 73eb5a5ce9713..659b77fa4584e 100644 --- a/tests/cases/compiler/selfInLambdas.ts +++ b/tests/cases/compiler/selfInLambdas.ts @@ -1,3 +1,6 @@ +// @noImplicitAny: true +// @noImplicitThis: true + interface MouseEvent { x: number; y: number; diff --git a/tests/cases/compiler/thisBinding2.ts b/tests/cases/compiler/thisBinding2.ts index 5d330c9e908b2..b478ce9338f4c 100644 --- a/tests/cases/compiler/thisBinding2.ts +++ b/tests/cases/compiler/thisBinding2.ts @@ -1,3 +1,6 @@ +// @noImplicitAny: true +// @noImplicitThis: true + class C { x: number; constructor() { diff --git a/tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts b/tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts index b70f064f43a8c..0671fc785076d 100644 --- a/tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts +++ b/tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts @@ -1,3 +1,6 @@ +// @noImplicitAny: true +// @noImplicitThis: true + interface I { n: number; explicitThis(this: this, m: number): number; diff --git a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts index 1c80e21aa160a..54dc9fa8a1723 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts @@ -1,3 +1,6 @@ +// @noImplicitAny: true +// @noImplicitThis: true + interface IndexedWithThis { // this is a workaround for React init?: (this: this) => void; diff --git a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts index 599caf70f3001..00550cdf25cf3 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts @@ -1,3 +1,6 @@ +// @noImplicitAny: true +// @noImplicitThis: true + let o = { d: "bar", m() { From f77cd8e54bcdeb6528e091740ddaaa20063f9544 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 28 Feb 2017 16:11:05 -0800 Subject: [PATCH 23/26] Accept new baselines --- tests/baselines/reference/castTest.symbols | 6 -- tests/baselines/reference/castTest.types | 16 ++-- .../commentsOnObjectLiteral3.symbols | 7 -- .../reference/commentsOnObjectLiteral3.types | 26 ++--- ...declFileObjectLiteralWithAccessors.symbols | 3 - .../declFileObjectLiteralWithAccessors.types | 6 +- ...eclFileObjectLiteralWithOnlySetter.symbols | 3 - .../declFileObjectLiteralWithOnlySetter.types | 6 +- ...iationAssignmentWithIndexingOnLHS3.symbols | 7 -- ...ntiationAssignmentWithIndexingOnLHS3.types | 12 +-- .../reference/fatarrowfunctions.symbols | 5 - .../reference/fatarrowfunctions.types | 12 +-- .../fatarrowfunctionsInFunctions.symbols | 5 - .../fatarrowfunctionsInFunctions.types | 16 ++-- .../looseThisTypeInFunctions.errors.txt | 11 ++- .../reference/looseThisTypeInFunctions.js | 1 + .../baselines/reference/objectSpread.symbols | 3 - tests/baselines/reference/objectSpread.types | 12 +-- tests/baselines/reference/selfInLambdas.js | 1 + .../baselines/reference/selfInLambdas.symbols | 71 +++++++------- tests/baselines/reference/selfInLambdas.types | 1 + .../reference/thisBinding2.errors.txt | 28 ++++++ tests/baselines/reference/thisBinding2.js | 1 + .../reference/thisInObjectLiterals.errors.txt | 25 ----- .../reference/thisInObjectLiterals.symbols | 45 +++++++++ .../reference/thisInObjectLiterals.types | 50 ++++++++++ .../thisInPropertyBoundDeclarations.symbols | 2 - .../thisInPropertyBoundDeclarations.types | 12 +-- .../reference/thisTypeInFunctions2.errors.txt | 60 ++++++++++++ .../reference/thisTypeInFunctions2.js | 1 + .../reference/thisTypeInObjectLiterals.js | 1 + .../thisTypeInObjectLiterals.symbols | 95 ++++++++++--------- .../reference/thisTypeInObjectLiterals.types | 1 + .../throwInEnclosingStatements.symbols | 1 - .../throwInEnclosingStatements.types | 2 +- .../reference/underscoreTest1.symbols | 6 -- .../baselines/reference/underscoreTest1.types | 12 +-- 37 files changed, 346 insertions(+), 226 deletions(-) create mode 100644 tests/baselines/reference/thisBinding2.errors.txt delete mode 100644 tests/baselines/reference/thisInObjectLiterals.errors.txt create mode 100644 tests/baselines/reference/thisInObjectLiterals.symbols create mode 100644 tests/baselines/reference/thisInObjectLiterals.types create mode 100644 tests/baselines/reference/thisTypeInFunctions2.errors.txt diff --git a/tests/baselines/reference/castTest.symbols b/tests/baselines/reference/castTest.symbols index 0baee00ec47d4..944cc8238e6e4 100644 --- a/tests/baselines/reference/castTest.symbols +++ b/tests/baselines/reference/castTest.symbols @@ -71,13 +71,7 @@ var p_cast = ({ return new Point(this.x + dx, this.y + dy); >Point : Symbol(Point, Decl(castTest.ts, 11, 37)) ->this.x : Symbol(Point.x, Decl(castTest.ts, 14, 1)) ->this : Symbol(Point, Decl(castTest.ts, 11, 37)) ->x : Symbol(Point.x, Decl(castTest.ts, 14, 1)) >dx : Symbol(dx, Decl(castTest.ts, 25, 18)) ->this.y : Symbol(Point.y, Decl(castTest.ts, 15, 14)) ->this : Symbol(Point, Decl(castTest.ts, 11, 37)) ->y : Symbol(Point.y, Decl(castTest.ts, 15, 14)) >dy : Symbol(dy, Decl(castTest.ts, 25, 21)) }, diff --git a/tests/baselines/reference/castTest.types b/tests/baselines/reference/castTest.types index 08c9853dca636..666b2ccf78e05 100644 --- a/tests/baselines/reference/castTest.types +++ b/tests/baselines/reference/castTest.types @@ -91,15 +91,15 @@ var p_cast = ({ return new Point(this.x + dx, this.y + dy); >new Point(this.x + dx, this.y + dy) : Point >Point : typeof Point ->this.x + dx : number ->this.x : number ->this : Point ->x : number +>this.x + dx : any +>this.x : any +>this : any +>x : any >dx : number ->this.y + dy : number ->this.y : number ->this : Point ->y : number +>this.y + dy : any +>this.y : any +>this : any +>y : any >dy : number }, diff --git a/tests/baselines/reference/commentsOnObjectLiteral3.symbols b/tests/baselines/reference/commentsOnObjectLiteral3.symbols index 34b4c706b42ae..3d58fe2d6d7eb 100644 --- a/tests/baselines/reference/commentsOnObjectLiteral3.symbols +++ b/tests/baselines/reference/commentsOnObjectLiteral3.symbols @@ -21,10 +21,6 @@ var v = { >a : Symbol(a, Decl(commentsOnObjectLiteral3.ts, 8, 13), Decl(commentsOnObjectLiteral3.ts, 12, 18)) return this.prop; ->this.prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) ->this : Symbol(v, Decl(commentsOnObjectLiteral3.ts, 1, 7)) ->prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) - } /*trailing 1*/, //setter set a(value) { @@ -32,9 +28,6 @@ var v = { >value : Symbol(value, Decl(commentsOnObjectLiteral3.ts, 14, 7)) this.prop = value; ->this.prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) ->this : Symbol(v, Decl(commentsOnObjectLiteral3.ts, 1, 7)) ->prop : Symbol(prop, Decl(commentsOnObjectLiteral3.ts, 1, 9)) >value : Symbol(value, Decl(commentsOnObjectLiteral3.ts, 14, 7)) } // trailing 2 diff --git a/tests/baselines/reference/commentsOnObjectLiteral3.types b/tests/baselines/reference/commentsOnObjectLiteral3.types index b869e96140158..4053e7e3f8938 100644 --- a/tests/baselines/reference/commentsOnObjectLiteral3.types +++ b/tests/baselines/reference/commentsOnObjectLiteral3.types @@ -1,8 +1,8 @@ === tests/cases/compiler/commentsOnObjectLiteral3.ts === var v = { ->v : { prop: number; func: () => void; func1(): void; a: number; } ->{ //property prop: 1 /* multiple trailing comments */ /*trailing comments*/, //property func: function () { }, //PropertyName + CallSignature func1() { }, //getter get a() { return this.prop; } /*trailing 1*/, //setter set a(value) { this.prop = value; } // trailing 2} : { prop: number; func: () => void; func1(): void; a: number; } +>v : { prop: number; func: () => void; func1(): void; a: any; } +>{ //property prop: 1 /* multiple trailing comments */ /*trailing comments*/, //property func: function () { }, //PropertyName + CallSignature func1() { }, //getter get a() { return this.prop; } /*trailing 1*/, //setter set a(value) { this.prop = value; } // trailing 2} : { prop: number; func: () => void; func1(): void; a: any; } //property prop: 1 /* multiple trailing comments */ /*trailing comments*/, @@ -21,25 +21,25 @@ var v = { //getter get a() { ->a : number +>a : any return this.prop; ->this.prop : number ->this : { prop: number; func: () => void; func1(): void; a: number; } ->prop : number +>this.prop : any +>this : any +>prop : any } /*trailing 1*/, //setter set a(value) { ->a : number ->value : number +>a : any +>value : any this.prop = value; ->this.prop = value : number ->this.prop : number ->this : { prop: number; func: () => void; func1(): void; a: number; } ->prop : number ->value : number +>this.prop = value : any +>this.prop : any +>this : any +>prop : any +>value : any } // trailing 2 }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols b/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols index df94b262c74cb..862b0b3781eff 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.symbols @@ -15,9 +15,6 @@ function /*1*/makePoint(x: number) { set x(a: number) { this.b = a; } >x : Symbol(x, Decl(declFileObjectLiteralWithAccessors.ts, 3, 14), Decl(declFileObjectLiteralWithAccessors.ts, 4, 30)) >a : Symbol(a, Decl(declFileObjectLiteralWithAccessors.ts, 5, 14)) ->this.b : Symbol(b, Decl(declFileObjectLiteralWithAccessors.ts, 2, 12)) ->this : Symbol(__object, Decl(declFileObjectLiteralWithAccessors.ts, 2, 10)) ->b : Symbol(b, Decl(declFileObjectLiteralWithAccessors.ts, 2, 12)) >a : Symbol(a, Decl(declFileObjectLiteralWithAccessors.ts, 5, 14)) }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithAccessors.types b/tests/baselines/reference/declFileObjectLiteralWithAccessors.types index 1c36f3211189c..389b88de565c7 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithAccessors.types +++ b/tests/baselines/reference/declFileObjectLiteralWithAccessors.types @@ -19,9 +19,9 @@ function /*1*/makePoint(x: number) { >x : number >a : number >this.b = a : number ->this.b : number ->this : { b: number; x: number; } ->b : number +>this.b : any +>this : any +>b : any >a : number }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols index 9dd2461b871fa..f747446614018 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.symbols @@ -11,9 +11,6 @@ function /*1*/makePoint(x: number) { set x(a: number) { this.b = a; } >x : Symbol(x, Decl(declFileObjectLiteralWithOnlySetter.ts, 3, 14)) >a : Symbol(a, Decl(declFileObjectLiteralWithOnlySetter.ts, 4, 14)) ->this.b : Symbol(b, Decl(declFileObjectLiteralWithOnlySetter.ts, 2, 12)) ->this : Symbol(__object, Decl(declFileObjectLiteralWithOnlySetter.ts, 2, 10)) ->b : Symbol(b, Decl(declFileObjectLiteralWithOnlySetter.ts, 2, 12)) >a : Symbol(a, Decl(declFileObjectLiteralWithOnlySetter.ts, 4, 14)) }; diff --git a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types index bf62561f57d5f..2f15818e0f2e5 100644 --- a/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types +++ b/tests/baselines/reference/declFileObjectLiteralWithOnlySetter.types @@ -15,9 +15,9 @@ function /*1*/makePoint(x: number) { >x : number >a : number >this.b = a : number ->this.b : number ->this : { b: number; x: number; } ->b : number +>this.b : any +>this : any +>b : any >a : number }; diff --git a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols index 785a56546811d..dbd5aa150dc5e 100644 --- a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols +++ b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.symbols @@ -8,18 +8,11 @@ var object = { get 0() { return this._0; ->this._0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) ->this : Symbol(object, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 12)) ->_0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) - }, set 0(x: number) { >x : Symbol(x, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 6, 10)) this._0 = x; ->this._0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) ->this : Symbol(object, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 12)) ->_0 : Symbol(_0, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 1, 14)) >x : Symbol(x, Decl(emitCompoundExponentiationAssignmentWithIndexingOnLHS3.ts, 6, 10)) }, diff --git a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types index 77026be2795c7..32e5b33e41132 100644 --- a/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types +++ b/tests/baselines/reference/emitCompoundExponentiationAssignmentWithIndexingOnLHS3.types @@ -10,9 +10,9 @@ var object = { get 0() { return this._0; ->this._0 : number ->this : { _0: number; 0: number; } ->_0 : number +>this._0 : any +>this : any +>_0 : any }, set 0(x: number) { @@ -20,9 +20,9 @@ var object = { this._0 = x; >this._0 = x : number ->this._0 : number ->this : { _0: number; 0: number; } ->_0 : number +>this._0 : any +>this : any +>_0 : any >x : number }, diff --git a/tests/baselines/reference/fatarrowfunctions.symbols b/tests/baselines/reference/fatarrowfunctions.symbols index 25213a9bbf8c9..6ed865b091459 100644 --- a/tests/baselines/reference/fatarrowfunctions.symbols +++ b/tests/baselines/reference/fatarrowfunctions.symbols @@ -163,11 +163,6 @@ var messenger = { setTimeout(() => { this.message.toString(); }, 3000); >setTimeout : Symbol(setTimeout, Decl(fatarrowfunctions.ts, 34, 1)) ->this.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) ->this.message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17)) ->this : Symbol(messenger, Decl(fatarrowfunctions.ts, 38, 15)) ->message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17)) ->toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) } }; diff --git a/tests/baselines/reference/fatarrowfunctions.types b/tests/baselines/reference/fatarrowfunctions.types index 1114ae365cbce..304c341c91640 100644 --- a/tests/baselines/reference/fatarrowfunctions.types +++ b/tests/baselines/reference/fatarrowfunctions.types @@ -234,12 +234,12 @@ var messenger = { >setTimeout(() => { this.message.toString(); }, 3000) : number >setTimeout : (expression: any, msec?: number, language?: any) => number >() => { this.message.toString(); } : () => void ->this.message.toString() : string ->this.message.toString : () => string ->this.message : string ->this : { message: string; start: () => void; } ->message : string ->toString : () => string +>this.message.toString() : any +>this.message.toString : any +>this.message : any +>this : any +>message : any +>toString : any >3000 : 3000 } }; diff --git a/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols b/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols index 977dd39460dfc..0a86affc21589 100644 --- a/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols +++ b/tests/baselines/reference/fatarrowfunctionsInFunctions.symbols @@ -16,17 +16,12 @@ var messenger = { var _self = this; >_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11)) ->this : Symbol(messenger, Decl(fatarrowfunctionsInFunctions.ts, 2, 15)) setTimeout(function() { >setTimeout : Symbol(setTimeout, Decl(fatarrowfunctionsInFunctions.ts, 0, 0)) _self.message.toString(); ->_self.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) ->_self.message : Symbol(message, Decl(fatarrowfunctionsInFunctions.ts, 2, 17)) >_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11)) ->message : Symbol(message, Decl(fatarrowfunctionsInFunctions.ts, 2, 17)) ->toString : Symbol(String.toString, Decl(lib.d.ts, --, --)) }, 3000); } diff --git a/tests/baselines/reference/fatarrowfunctionsInFunctions.types b/tests/baselines/reference/fatarrowfunctionsInFunctions.types index 88807f2a37b6b..8b9bd7ccd7a62 100644 --- a/tests/baselines/reference/fatarrowfunctionsInFunctions.types +++ b/tests/baselines/reference/fatarrowfunctionsInFunctions.types @@ -18,8 +18,8 @@ var messenger = { >function() { var _self = this; setTimeout(function() { _self.message.toString(); }, 3000); } : () => void var _self = this; ->_self : { message: string; start: () => void; } ->this : { message: string; start: () => void; } +>_self : any +>this : any setTimeout(function() { >setTimeout(function() { _self.message.toString(); }, 3000) : number @@ -27,12 +27,12 @@ var messenger = { >function() { _self.message.toString(); } : () => void _self.message.toString(); ->_self.message.toString() : string ->_self.message.toString : () => string ->_self.message : string ->_self : { message: string; start: () => void; } ->message : string ->toString : () => string +>_self.message.toString() : any +>_self.message.toString : any +>_self.message : any +>_self : any +>message : any +>toString : any }, 3000); >3000 : 3000 diff --git a/tests/baselines/reference/looseThisTypeInFunctions.errors.txt b/tests/baselines/reference/looseThisTypeInFunctions.errors.txt index 7e12a71440685..cf4dcbd7dd55d 100644 --- a/tests/baselines/reference/looseThisTypeInFunctions.errors.txt +++ b/tests/baselines/reference/looseThisTypeInFunctions.errors.txt @@ -1,13 +1,14 @@ -tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(21,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(22,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'. The 'this' types of each signature are incompatible. Type 'void' is not assignable to type 'C'. -tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(25,27): error TS2339: Property 'length' does not exist on type 'number'. -tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(33,28): error TS2339: Property 'length' does not exist on type 'number'. -tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(37,9): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'I'. -tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error TS2339: Property 'length' does not exist on type 'number'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(26,27): error TS2339: Property 'length' does not exist on type 'number'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(34,28): error TS2339: Property 'length' does not exist on type 'number'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(38,9): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'I'. +tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(47,20): error TS2339: Property 'length' does not exist on type 'number'. ==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (5 errors) ==== + interface I { n: number; explicitThis(this: this, m: number): number; diff --git a/tests/baselines/reference/looseThisTypeInFunctions.js b/tests/baselines/reference/looseThisTypeInFunctions.js index cb1fbcc8b9572..3e97691ade2ed 100644 --- a/tests/baselines/reference/looseThisTypeInFunctions.js +++ b/tests/baselines/reference/looseThisTypeInFunctions.js @@ -1,4 +1,5 @@ //// [looseThisTypeInFunctions.ts] + interface I { n: number; explicitThis(this: this, m: number): number; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 0538121e90c13..1ec2520e166f2 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -200,9 +200,6 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) >c : Symbol(c, Decl(objectSpread.ts, 45, 3)) >plus : Symbol(plus, Decl(objectSpread.ts, 49, 48)) ->this.p : Symbol(p, Decl(objectSpread.ts, 49, 12)) ->this : Symbol(cplus, Decl(objectSpread.ts, 49, 10)) ->p : Symbol(p, Decl(objectSpread.ts, 49, 12)) cplus.plus(); >cplus.plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 3a73672142525..950dab43465c7 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -263,13 +263,13 @@ let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } } >cplus : { p: number; plus(): void; } >p : number >plus : () => void ->{ ...c, plus() { return this.p + 1; } } : { plus(): number; p: number; } +>{ ...c, plus() { return this.p + 1; } } : { plus(): any; p: number; } >c : C ->plus : () => number ->this.p + 1 : number ->this.p : number ->this : { p: number; plus(): void; } ->p : number +>plus : () => any +>this.p + 1 : any +>this.p : any +>this : any +>p : any >1 : 1 cplus.plus(); diff --git a/tests/baselines/reference/selfInLambdas.js b/tests/baselines/reference/selfInLambdas.js index b143c0c9e4ea3..f965460671659 100644 --- a/tests/baselines/reference/selfInLambdas.js +++ b/tests/baselines/reference/selfInLambdas.js @@ -1,4 +1,5 @@ //// [selfInLambdas.ts] + interface MouseEvent { x: number; y: number; diff --git a/tests/baselines/reference/selfInLambdas.symbols b/tests/baselines/reference/selfInLambdas.symbols index 0a51113710ba9..8efadb7c07751 100644 --- a/tests/baselines/reference/selfInLambdas.symbols +++ b/tests/baselines/reference/selfInLambdas.symbols @@ -1,51 +1,52 @@ === tests/cases/compiler/selfInLambdas.ts === + interface MouseEvent { >MouseEvent : Symbol(MouseEvent, Decl(selfInLambdas.ts, 0, 0)) x: number; ->x : Symbol(MouseEvent.x, Decl(selfInLambdas.ts, 0, 22)) +>x : Symbol(MouseEvent.x, Decl(selfInLambdas.ts, 1, 22)) y: number; ->y : Symbol(MouseEvent.y, Decl(selfInLambdas.ts, 1, 14)) +>y : Symbol(MouseEvent.y, Decl(selfInLambdas.ts, 2, 14)) } declare var window: Window; ->window : Symbol(window, Decl(selfInLambdas.ts, 5, 11)) ->Window : Symbol(Window, Decl(selfInLambdas.ts, 5, 27)) +>window : Symbol(window, Decl(selfInLambdas.ts, 6, 11)) +>Window : Symbol(Window, Decl(selfInLambdas.ts, 6, 27)) interface Window { ->Window : Symbol(Window, Decl(selfInLambdas.ts, 5, 27)) +>Window : Symbol(Window, Decl(selfInLambdas.ts, 6, 27)) onmousemove: (ev: MouseEvent) => any; ->onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18)) ->ev : Symbol(ev, Decl(selfInLambdas.ts, 7, 18)) +>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 7, 18)) +>ev : Symbol(ev, Decl(selfInLambdas.ts, 8, 18)) >MouseEvent : Symbol(MouseEvent, Decl(selfInLambdas.ts, 0, 0)) } var o = { ->o : Symbol(o, Decl(selfInLambdas.ts, 10, 3)) +>o : Symbol(o, Decl(selfInLambdas.ts, 11, 3)) counter: 0, ->counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) +>counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9)) start: function() { ->start : Symbol(start, Decl(selfInLambdas.ts, 12, 15)) +>start : Symbol(start, Decl(selfInLambdas.ts, 13, 15)) window.onmousemove = () => { ->window.onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18)) ->window : Symbol(window, Decl(selfInLambdas.ts, 5, 11)) ->onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18)) +>window.onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 7, 18)) +>window : Symbol(window, Decl(selfInLambdas.ts, 6, 11)) +>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 7, 18)) this.counter++ ->this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) ->this : Symbol(o, Decl(selfInLambdas.ts, 10, 7)) ->counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) +>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9)) +>this : Symbol(o, Decl(selfInLambdas.ts, 11, 7)) +>counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9)) var f = () => this.counter; ->f : Symbol(f, Decl(selfInLambdas.ts, 18, 15)) ->this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) ->this : Symbol(o, Decl(selfInLambdas.ts, 10, 7)) ->counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9)) +>f : Symbol(f, Decl(selfInLambdas.ts, 19, 15)) +>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9)) +>this : Symbol(o, Decl(selfInLambdas.ts, 11, 7)) +>counter : Symbol(counter, Decl(selfInLambdas.ts, 11, 9)) } @@ -56,39 +57,39 @@ var o = { class X { ->X : Symbol(X, Decl(selfInLambdas.ts, 24, 1)) +>X : Symbol(X, Decl(selfInLambdas.ts, 25, 1)) private value = "value"; ->value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9)) +>value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9)) public foo() { ->foo : Symbol(X.foo, Decl(selfInLambdas.ts, 29, 25)) +>foo : Symbol(X.foo, Decl(selfInLambdas.ts, 30, 25)) var outer= () => { ->outer : Symbol(outer, Decl(selfInLambdas.ts, 32, 5)) +>outer : Symbol(outer, Decl(selfInLambdas.ts, 33, 5)) var x = this.value; ->x : Symbol(x, Decl(selfInLambdas.ts, 33, 15)) ->this.value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9)) ->this : Symbol(X, Decl(selfInLambdas.ts, 24, 1)) ->value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9)) +>x : Symbol(x, Decl(selfInLambdas.ts, 34, 15)) +>this.value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9)) +>this : Symbol(X, Decl(selfInLambdas.ts, 25, 1)) +>value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9)) var inner = () => { ->inner : Symbol(inner, Decl(selfInLambdas.ts, 34, 15)) +>inner : Symbol(inner, Decl(selfInLambdas.ts, 35, 15)) var y = this.value; ->y : Symbol(y, Decl(selfInLambdas.ts, 35, 19)) ->this.value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9)) ->this : Symbol(X, Decl(selfInLambdas.ts, 24, 1)) ->value : Symbol(X.value, Decl(selfInLambdas.ts, 28, 9)) +>y : Symbol(y, Decl(selfInLambdas.ts, 36, 19)) +>this.value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9)) +>this : Symbol(X, Decl(selfInLambdas.ts, 25, 1)) +>value : Symbol(X.value, Decl(selfInLambdas.ts, 29, 9)) } inner(); ->inner : Symbol(inner, Decl(selfInLambdas.ts, 34, 15)) +>inner : Symbol(inner, Decl(selfInLambdas.ts, 35, 15)) }; outer(); ->outer : Symbol(outer, Decl(selfInLambdas.ts, 32, 5)) +>outer : Symbol(outer, Decl(selfInLambdas.ts, 33, 5)) } } diff --git a/tests/baselines/reference/selfInLambdas.types b/tests/baselines/reference/selfInLambdas.types index a26e1e0bf286d..251cfb2d0c3ae 100644 --- a/tests/baselines/reference/selfInLambdas.types +++ b/tests/baselines/reference/selfInLambdas.types @@ -1,4 +1,5 @@ === tests/cases/compiler/selfInLambdas.ts === + interface MouseEvent { >MouseEvent : MouseEvent diff --git a/tests/baselines/reference/thisBinding2.errors.txt b/tests/baselines/reference/thisBinding2.errors.txt new file mode 100644 index 0000000000000..ddfa078a2d270 --- /dev/null +++ b/tests/baselines/reference/thisBinding2.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/thisBinding2.ts(11,11): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. + + +==== tests/cases/compiler/thisBinding2.ts (1 errors) ==== + + class C { + x: number; + constructor() { + this.x = (() => { + var x = 1; + return this.x; + })(); + this.x = function() { + var x = 1; + return this.x; + ~~~~ +!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation. + }(); + } + } + declare function setTimeout(expression: any, msec?: number, language?: any): number; + var messenger = { + message: "Hello World", + start: function () { + return setTimeout(() => { var x = this.message; }, 3000); + } + }; + \ No newline at end of file diff --git a/tests/baselines/reference/thisBinding2.js b/tests/baselines/reference/thisBinding2.js index 142cd9db4a5a2..732cb4fac00e0 100644 --- a/tests/baselines/reference/thisBinding2.js +++ b/tests/baselines/reference/thisBinding2.js @@ -1,4 +1,5 @@ //// [thisBinding2.ts] + class C { x: number; constructor() { diff --git a/tests/baselines/reference/thisInObjectLiterals.errors.txt b/tests/baselines/reference/thisInObjectLiterals.errors.txt deleted file mode 100644 index 3da8430802d6a..0000000000000 --- a/tests/baselines/reference/thisInObjectLiterals.errors.txt +++ /dev/null @@ -1,25 +0,0 @@ -tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(15,21): error TS2339: Property 'spaaace' does not exist on type '{ f(): any; }'. - - -==== tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts (1 errors) ==== - class MyClass { - t: number; - - fn() { - type ContainingThis = this; - //type of 'this' in an object literal is the containing scope's this - var t = { x: this, y: this.t }; - var t: { x: ContainingThis; y: number }; - } - } - - //type of 'this' in an object literal method is the type of the object literal - var obj = { - f() { - return this.spaaace; - ~~~~~~~ -!!! error TS2339: Property 'spaaace' does not exist on type '{ f(): any; }'. - } - }; - var obj: { f: () => any; }; - \ No newline at end of file diff --git a/tests/baselines/reference/thisInObjectLiterals.symbols b/tests/baselines/reference/thisInObjectLiterals.symbols new file mode 100644 index 0000000000000..51f30009b6527 --- /dev/null +++ b/tests/baselines/reference/thisInObjectLiterals.symbols @@ -0,0 +1,45 @@ +=== tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts === +class MyClass { +>MyClass : Symbol(MyClass, Decl(thisInObjectLiterals.ts, 0, 0)) + + t: number; +>t : Symbol(MyClass.t, Decl(thisInObjectLiterals.ts, 0, 15)) + + fn() { +>fn : Symbol(MyClass.fn, Decl(thisInObjectLiterals.ts, 1, 14)) + + type ContainingThis = this; +>ContainingThis : Symbol(ContainingThis, Decl(thisInObjectLiterals.ts, 3, 10)) + + //type of 'this' in an object literal is the containing scope's this + var t = { x: this, y: this.t }; +>t : Symbol(t, Decl(thisInObjectLiterals.ts, 6, 11), Decl(thisInObjectLiterals.ts, 7, 11)) +>x : Symbol(x, Decl(thisInObjectLiterals.ts, 6, 17)) +>this : Symbol(MyClass, Decl(thisInObjectLiterals.ts, 0, 0)) +>y : Symbol(y, Decl(thisInObjectLiterals.ts, 6, 26)) +>this.t : Symbol(MyClass.t, Decl(thisInObjectLiterals.ts, 0, 15)) +>this : Symbol(MyClass, Decl(thisInObjectLiterals.ts, 0, 0)) +>t : Symbol(MyClass.t, Decl(thisInObjectLiterals.ts, 0, 15)) + + var t: { x: ContainingThis; y: number }; +>t : Symbol(t, Decl(thisInObjectLiterals.ts, 6, 11), Decl(thisInObjectLiterals.ts, 7, 11)) +>x : Symbol(x, Decl(thisInObjectLiterals.ts, 7, 16)) +>ContainingThis : Symbol(ContainingThis, Decl(thisInObjectLiterals.ts, 3, 10)) +>y : Symbol(y, Decl(thisInObjectLiterals.ts, 7, 35)) + } +} + +//type of 'this' in an object literal method is the type of the object literal +var obj = { +>obj : Symbol(obj, Decl(thisInObjectLiterals.ts, 12, 3), Decl(thisInObjectLiterals.ts, 17, 3)) + + f() { +>f : Symbol(f, Decl(thisInObjectLiterals.ts, 12, 11)) + + return this.spaaace; + } +}; +var obj: { f: () => any; }; +>obj : Symbol(obj, Decl(thisInObjectLiterals.ts, 12, 3), Decl(thisInObjectLiterals.ts, 17, 3)) +>f : Symbol(f, Decl(thisInObjectLiterals.ts, 17, 10)) + diff --git a/tests/baselines/reference/thisInObjectLiterals.types b/tests/baselines/reference/thisInObjectLiterals.types new file mode 100644 index 0000000000000..b707a473dfb07 --- /dev/null +++ b/tests/baselines/reference/thisInObjectLiterals.types @@ -0,0 +1,50 @@ +=== tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts === +class MyClass { +>MyClass : MyClass + + t: number; +>t : number + + fn() { +>fn : () => void + + type ContainingThis = this; +>ContainingThis : this + + //type of 'this' in an object literal is the containing scope's this + var t = { x: this, y: this.t }; +>t : { x: this; y: number; } +>{ x: this, y: this.t } : { x: this; y: number; } +>x : this +>this : this +>y : number +>this.t : number +>this : this +>t : number + + var t: { x: ContainingThis; y: number }; +>t : { x: this; y: number; } +>x : this +>ContainingThis : this +>y : number + } +} + +//type of 'this' in an object literal method is the type of the object literal +var obj = { +>obj : { f(): any; } +>{ f() { return this.spaaace; }} : { f(): any; } + + f() { +>f : () => any + + return this.spaaace; +>this.spaaace : any +>this : any +>spaaace : any + } +}; +var obj: { f: () => any; }; +>obj : { f(): any; } +>f : () => any + diff --git a/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols b/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols index 6afdd73f77f05..12d3b2db31eb5 100644 --- a/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols +++ b/tests/baselines/reference/thisInPropertyBoundDeclarations.symbols @@ -70,7 +70,6 @@ class A { a: function() { return this; }, >a : Symbol(a, Decl(thisInPropertyBoundDeclarations.ts, 33, 13)) ->this : Symbol(__object, Decl(thisInPropertyBoundDeclarations.ts, 33, 11)) }; @@ -80,7 +79,6 @@ class A { return { a: function() { return this; }, >a : Symbol(a, Decl(thisInPropertyBoundDeclarations.ts, 38, 16)) ->this : Symbol(__object, Decl(thisInPropertyBoundDeclarations.ts, 38, 14)) }; }; diff --git a/tests/baselines/reference/thisInPropertyBoundDeclarations.types b/tests/baselines/reference/thisInPropertyBoundDeclarations.types index 7c2b28bfb3e86..b783c5c1b5fee 100644 --- a/tests/baselines/reference/thisInPropertyBoundDeclarations.types +++ b/tests/baselines/reference/thisInPropertyBoundDeclarations.types @@ -84,9 +84,9 @@ class A { >{ a: function() { return this; }, } : { a: () => any; } a: function() { return this; }, ->a : () => { a: any; } ->function() { return this; } : () => { a: any; } ->this : { a: () => any; } +>a : () => any +>function() { return this; } : () => any +>this : any }; @@ -98,9 +98,9 @@ class A { >{ a: function() { return this; }, } : { a: () => any; } a: function() { return this; }, ->a : () => { a: any; } ->function() { return this; } : () => { a: any; } ->this : { a: () => any; } +>a : () => any +>function() { return this; } : () => any +>this : any }; }; diff --git a/tests/baselines/reference/thisTypeInFunctions2.errors.txt b/tests/baselines/reference/thisTypeInFunctions2.errors.txt new file mode 100644 index 0000000000000..86721a769711e --- /dev/null +++ b/tests/baselines/reference/thisTypeInFunctions2.errors.txt @@ -0,0 +1,60 @@ +tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts(15,5): error TS7010: 'foo', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/conformance/types/thisType/thisTypeInFunctions2.ts (1 errors) ==== + + interface IndexedWithThis { + // this is a workaround for React + init?: (this: this) => void; + willDestroy?: (this: any) => void; + [propName: string]: number | string | boolean | symbol | undefined | null | {} | ((this: any, ...args:any[]) => any); + } + interface IndexedWithoutThis { + // this is what React would like to write (and what they write today) + init?: () => void; + willDestroy?: () => void; + [propName: string]: any; + } + interface SimpleInterface { + foo(n: string); + ~~~~~~~~~~~~~~~ +!!! error TS7010: 'foo', which lacks return-type annotation, implicitly has an 'any' return type. + bar(): number; + } + declare function extend1(args: IndexedWithThis): void; + declare function extend2(args: IndexedWithoutThis): void; + declare function simple(arg: SimpleInterface): void; + + extend1({ + init() { + this // this: IndexedWithThis because of contextual typing. + // this.mine + this.willDestroy + }, + mine: 12, + foo() { + this.url; // this: any because 'foo' matches the string indexer + this.willDestroy; + } + }); + extend2({ + init() { + this // this: containing object literal type + this.mine + }, + mine: 13, + foo() { + this // this: containing object literal type + this.mine + } + }); + + simple({ + foo(n) { + return n.length + this.bar(); + }, + bar() { + return 14; + } + }) + \ No newline at end of file diff --git a/tests/baselines/reference/thisTypeInFunctions2.js b/tests/baselines/reference/thisTypeInFunctions2.js index 978f79483b03a..7608629ea89e6 100644 --- a/tests/baselines/reference/thisTypeInFunctions2.js +++ b/tests/baselines/reference/thisTypeInFunctions2.js @@ -1,4 +1,5 @@ //// [thisTypeInFunctions2.ts] + interface IndexedWithThis { // this is a workaround for React init?: (this: this) => void; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals.js b/tests/baselines/reference/thisTypeInObjectLiterals.js index 342c9d58c8490..18f0a6407bcfb 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals.js +++ b/tests/baselines/reference/thisTypeInObjectLiterals.js @@ -1,4 +1,5 @@ //// [thisTypeInObjectLiterals.ts] + let o = { d: "bar", m() { diff --git a/tests/baselines/reference/thisTypeInObjectLiterals.symbols b/tests/baselines/reference/thisTypeInObjectLiterals.symbols index fd6d6ecebd5c8..374c790bd8fff 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals.symbols +++ b/tests/baselines/reference/thisTypeInObjectLiterals.symbols @@ -1,104 +1,105 @@ === tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts === + let o = { ->o : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 0, 3)) +>o : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 1, 3)) d: "bar", ->d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 1, 9)) m() { ->m : Symbol(m, Decl(thisTypeInObjectLiterals.ts, 1, 13)) +>m : Symbol(m, Decl(thisTypeInObjectLiterals.ts, 2, 13)) return this.d.length; >this.d.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) ->this : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 0, 7)) ->d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 1, 9)) +>this : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 1, 7)) +>d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 1, 9)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) }, f: function() { ->f : Symbol(f, Decl(thisTypeInObjectLiterals.ts, 4, 6)) +>f : Symbol(f, Decl(thisTypeInObjectLiterals.ts, 5, 6)) return this.d.length; >this.d.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) ->this : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 0, 7)) ->d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 0, 9)) +>this.d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 1, 9)) +>this : Symbol(o, Decl(thisTypeInObjectLiterals.ts, 1, 7)) +>d : Symbol(d, Decl(thisTypeInObjectLiterals.ts, 1, 9)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) } } let mutuallyRecursive = { ->mutuallyRecursive : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 3)) +>mutuallyRecursive : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 3)) a: 100, ->a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) +>a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 11, 25)) start() { ->start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 11, 11)) +>start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 12, 11)) return this.passthrough(this.a); ->this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) ->passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->this.a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) ->this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) ->a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 10, 25)) +>this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 15, 6)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 23)) +>passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 15, 6)) +>this.a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 11, 25)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 23)) +>a : Symbol(a, Decl(thisTypeInObjectLiterals.ts, 11, 25)) }, passthrough(n: number) { ->passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 15, 16)) +>passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 15, 6)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 16, 16)) return this.sub1(n); ->this.sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) ->this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) ->sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 15, 16)) +>this.sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 18, 6)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 23)) +>sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 18, 6)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 16, 16)) }, sub1(n: number): number { ->sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 17, 6)) ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) +>sub1 : Symbol(sub1, Decl(thisTypeInObjectLiterals.ts, 18, 6)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 19, 9)) if (n > 0) { ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 19, 9)) return this.passthrough(n - 1); ->this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 23)) ->passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 14, 6)) ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) +>this.passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 15, 6)) +>this : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 23)) +>passthrough : Symbol(passthrough, Decl(thisTypeInObjectLiterals.ts, 15, 6)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 19, 9)) } return n; ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 18, 9)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 19, 9)) } } var i: number = mutuallyRecursive.start(); ->i : Symbol(i, Decl(thisTypeInObjectLiterals.ts, 25, 3)) ->mutuallyRecursive.start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 11, 11)) ->mutuallyRecursive : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 3)) ->start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 11, 11)) +>i : Symbol(i, Decl(thisTypeInObjectLiterals.ts, 26, 3)) +>mutuallyRecursive.start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 12, 11)) +>mutuallyRecursive : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 3)) +>start : Symbol(start, Decl(thisTypeInObjectLiterals.ts, 12, 11)) interface I { ->I : Symbol(I, Decl(thisTypeInObjectLiterals.ts, 25, 42)) +>I : Symbol(I, Decl(thisTypeInObjectLiterals.ts, 26, 42)) a: number; ->a : Symbol(I.a, Decl(thisTypeInObjectLiterals.ts, 26, 13)) +>a : Symbol(I.a, Decl(thisTypeInObjectLiterals.ts, 27, 13)) start(): number; ->start : Symbol(I.start, Decl(thisTypeInObjectLiterals.ts, 27, 14)) +>start : Symbol(I.start, Decl(thisTypeInObjectLiterals.ts, 28, 14)) passthrough(n: number): number; ->passthrough : Symbol(I.passthrough, Decl(thisTypeInObjectLiterals.ts, 28, 20)) ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 29, 16)) +>passthrough : Symbol(I.passthrough, Decl(thisTypeInObjectLiterals.ts, 29, 20)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 30, 16)) sub1(n: number): number; ->sub1 : Symbol(I.sub1, Decl(thisTypeInObjectLiterals.ts, 29, 35)) ->n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 30, 9)) +>sub1 : Symbol(I.sub1, Decl(thisTypeInObjectLiterals.ts, 30, 35)) +>n : Symbol(n, Decl(thisTypeInObjectLiterals.ts, 31, 9)) } var impl: I = mutuallyRecursive; ->impl : Symbol(impl, Decl(thisTypeInObjectLiterals.ts, 32, 3)) ->I : Symbol(I, Decl(thisTypeInObjectLiterals.ts, 25, 42)) ->mutuallyRecursive : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 10, 3)) +>impl : Symbol(impl, Decl(thisTypeInObjectLiterals.ts, 33, 3)) +>I : Symbol(I, Decl(thisTypeInObjectLiterals.ts, 26, 42)) +>mutuallyRecursive : Symbol(mutuallyRecursive, Decl(thisTypeInObjectLiterals.ts, 11, 3)) diff --git a/tests/baselines/reference/thisTypeInObjectLiterals.types b/tests/baselines/reference/thisTypeInObjectLiterals.types index d5c6d851faf15..d4e6188b9cfc8 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals.types @@ -1,4 +1,5 @@ === tests/cases/conformance/types/thisType/thisTypeInObjectLiterals.ts === + let o = { >o : { d: string; m(): number; f: () => number; } >{ d: "bar", m() { return this.d.length; }, f: function() { return this.d.length; }} : { d: string; m(): number; f: () => number; } diff --git a/tests/baselines/reference/throwInEnclosingStatements.symbols b/tests/baselines/reference/throwInEnclosingStatements.symbols index 36dcd3cfcbdb5..63ed9dde5784a 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.symbols +++ b/tests/baselines/reference/throwInEnclosingStatements.symbols @@ -89,7 +89,6 @@ var aa = { >biz : Symbol(biz, Decl(throwInEnclosingStatements.ts, 41, 10)) throw this; ->this : Symbol(aa, Decl(throwInEnclosingStatements.ts, 40, 8)) } } diff --git a/tests/baselines/reference/throwInEnclosingStatements.types b/tests/baselines/reference/throwInEnclosingStatements.types index d859bbd639237..2d99ac435aebf 100644 --- a/tests/baselines/reference/throwInEnclosingStatements.types +++ b/tests/baselines/reference/throwInEnclosingStatements.types @@ -104,7 +104,7 @@ var aa = { >biz : () => void throw this; ->this : { id: number; biz(): void; } +>this : any } } diff --git a/tests/baselines/reference/underscoreTest1.symbols b/tests/baselines/reference/underscoreTest1.symbols index 3b578be8165fe..41b0c8110275a 100644 --- a/tests/baselines/reference/underscoreTest1.symbols +++ b/tests/baselines/reference/underscoreTest1.symbols @@ -395,16 +395,10 @@ var buttonView = { onClick: function () { alert('clicked: ' + this.label); }, >onClick : Symbol(onClick, Decl(underscoreTest1_underscoreTests.ts, 97, 24)) >alert : Symbol(alert, Decl(underscoreTest1_underscoreTests.ts, 2, 14)) ->this.label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) ->this : Symbol(buttonView, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) ->label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) onHover: function () { alert('hovering: ' + this.label); } >onHover : Symbol(onHover, Decl(underscoreTest1_underscoreTests.ts, 98, 62)) >alert : Symbol(alert, Decl(underscoreTest1_underscoreTests.ts, 2, 14)) ->this.label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) ->this : Symbol(buttonView, Decl(underscoreTest1_underscoreTests.ts, 96, 16)) ->label : Symbol(label, Decl(underscoreTest1_underscoreTests.ts, 96, 18)) }; _.bindAll(buttonView); diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 26e30ae6f5239..afcc807b756bd 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -827,9 +827,9 @@ var buttonView = { >alert : (x: string) => void >'clicked: ' + this.label : string >'clicked: ' : "clicked: " ->this.label : string ->this : { label: string; onClick: () => void; onHover: () => void; } ->label : string +>this.label : any +>this : any +>label : any onHover: function () { alert('hovering: ' + this.label); } >onHover : () => void @@ -838,9 +838,9 @@ var buttonView = { >alert : (x: string) => void >'hovering: ' + this.label : string >'hovering: ' : "hovering: " ->this.label : string ->this : { label: string; onClick: () => void; onHover: () => void; } ->label : string +>this.label : any +>this : any +>label : any }; _.bindAll(buttonView); From 9d1b325e09f3f71071b213e819a8aa36b99b32e7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 1 Mar 2017 06:31:34 -0800 Subject: [PATCH 24/26] Update another test --- .../reference/thisInObjectLiterals.errors.txt | 29 +++++++++++++++++++ .../reference/thisInObjectLiterals.js | 1 + .../thisKeyword/thisInObjectLiterals.ts | 3 ++ 3 files changed, 33 insertions(+) create mode 100644 tests/baselines/reference/thisInObjectLiterals.errors.txt diff --git a/tests/baselines/reference/thisInObjectLiterals.errors.txt b/tests/baselines/reference/thisInObjectLiterals.errors.txt new file mode 100644 index 0000000000000..52ff6789559f0 --- /dev/null +++ b/tests/baselines/reference/thisInObjectLiterals.errors.txt @@ -0,0 +1,29 @@ +tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(15,5): error TS7023: 'f' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts(16,21): error TS2339: Property 'spaaace' does not exist on type '{ f(): any; }'. + + +==== tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts (2 errors) ==== + + class MyClass { + t: number; + + fn() { + type ContainingThis = this; + //type of 'this' in an object literal is the containing scope's this + var t = { x: this, y: this.t }; + var t: { x: ContainingThis; y: number }; + } + } + + //type of 'this' in an object literal method is the type of the object literal + var obj = { + f() { + ~ +!!! error TS7023: 'f' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + return this.spaaace; + ~~~~~~~ +!!! error TS2339: Property 'spaaace' does not exist on type '{ f(): any; }'. + } + }; + var obj: { f: () => any; }; + \ No newline at end of file diff --git a/tests/baselines/reference/thisInObjectLiterals.js b/tests/baselines/reference/thisInObjectLiterals.js index 6331f12105d91..33a55cd5c71db 100644 --- a/tests/baselines/reference/thisInObjectLiterals.js +++ b/tests/baselines/reference/thisInObjectLiterals.js @@ -1,4 +1,5 @@ //// [thisInObjectLiterals.ts] + class MyClass { t: number; diff --git a/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts b/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts index 6219586b6e590..7ba7d5b2e918e 100644 --- a/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts +++ b/tests/cases/conformance/expressions/thisKeyword/thisInObjectLiterals.ts @@ -1,3 +1,6 @@ +// @noImplicitAny: true +// @noImplicitThis: true + class MyClass { t: number; From 7561cdf6bf3b9187f6fdfc704f8f867615fd1d59 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 1 Mar 2017 17:16:09 -0800 Subject: [PATCH 25/26] Add ThisType to Object.{create|defineProperty|defineProperties} --- src/lib/es5.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 711981888a923..04743f7d77f4b 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -147,7 +147,7 @@ interface ObjectConstructor { * @param o Object to use as a prototype. May be null * @param properties JavaScript object that contains one or more property descriptors. */ - create(o: object | null, properties: PropertyDescriptorMap): any; + create(o: object | null, properties: PropertyDescriptorMap & ThisType): any; /** * Adds a property to an object, or modifies attributes of an existing property. @@ -155,14 +155,14 @@ interface ObjectConstructor { * @param p The property name. * @param attributes Descriptor for the property. It can be for a data property or an accessor property. */ - defineProperty(o: any, p: string, attributes: PropertyDescriptor): any; + defineProperty(o: any, p: string, attributes: PropertyDescriptor & ThisType): any; /** * Adds one or more properties to an object, and/or modifies attributes of existing properties. * @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object. * @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property. */ - defineProperties(o: any, properties: PropertyDescriptorMap): any; + defineProperties(o: any, properties: PropertyDescriptorMap & ThisType): any; /** * Prevents the modification of attributes of existing properties, and prevents the addition of new properties. From 258bb4ff55f0336ac4df67056296eca23eaf783b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 1 Mar 2017 17:16:35 -0800 Subject: [PATCH 26/26] Accept new baselines --- .../reference/getterSetterNonAccessor.types | 4 +- tests/baselines/reference/objectCreate.types | 40 +++++++++---------- tests/baselines/reference/objectCreate2.types | 40 +++++++++---------- .../reference/objectLitGetterSetter.types | 4 +- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/baselines/reference/getterSetterNonAccessor.types b/tests/baselines/reference/getterSetterNonAccessor.types index f5eb22296f3e5..4fbff67ee49ff 100644 --- a/tests/baselines/reference/getterSetterNonAccessor.types +++ b/tests/baselines/reference/getterSetterNonAccessor.types @@ -9,9 +9,9 @@ function setFunc(v){} Object.defineProperty({}, "0", ({ >Object.defineProperty({}, "0", ({ get: getFunc, set: setFunc, configurable: true })) : any ->Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any +>Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any >Object : ObjectConstructor ->defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any +>defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any >{} : {} >"0" : "0" >({ get: getFunc, set: setFunc, configurable: true }) : PropertyDescriptor diff --git a/tests/baselines/reference/objectCreate.types b/tests/baselines/reference/objectCreate.types index b4e0e72061ede..8bf433e53fe3f 100644 --- a/tests/baselines/reference/objectCreate.types +++ b/tests/baselines/reference/objectCreate.types @@ -9,17 +9,17 @@ declare var union: null | { a: number, b: string }; var n = Object.create(null); // object >n : any >Object.create(null) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >null : null var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } >t : any >Object.create({ a: 1, b: "" }) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -29,43 +29,43 @@ var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } var u = Object.create(union); // object | {a: number, b: string } >u : any >Object.create(union) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >union : { a: number; b: string; } | null var e = Object.create({}); // {} >e : any >Object.create({}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >{} : {} var o = Object.create({}); // object >o : any >Object.create({}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >{} : object >{} : {} var a = Object.create(null, {}); // any >a : any >Object.create(null, {}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >null : null >{} : {} var a = Object.create({ a: 1, b: "" }, {}); >a : any >Object.create({ a: 1, b: "" }, {}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -76,27 +76,27 @@ var a = Object.create({ a: 1, b: "" }, {}); var a = Object.create(union, {}); >a : any >Object.create(union, {}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >union : { a: number; b: string; } | null >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >{} : {} >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap): any; } +>create : { (o: object | null): any; (o: object | null, properties: PropertyDescriptorMap & ThisType): any; } >{} : object >{} : {} >{} : {} diff --git a/tests/baselines/reference/objectCreate2.types b/tests/baselines/reference/objectCreate2.types index 3e19c08bfc0c6..1602d70d57189 100644 --- a/tests/baselines/reference/objectCreate2.types +++ b/tests/baselines/reference/objectCreate2.types @@ -9,17 +9,17 @@ declare var union: null | { a: number, b: string }; var n = Object.create(null); // any >n : any >Object.create(null) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >null : null var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } >t : any >Object.create({ a: 1, b: "" }) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -29,43 +29,43 @@ var t = Object.create({ a: 1, b: "" }); // {a: number, b: string } var u = Object.create(union); // {a: number, b: string } >u : any >Object.create(union) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >union : { a: number; b: string; } var e = Object.create({}); // {} >e : any >Object.create({}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >{} : {} var o = Object.create({}); // object >o : any >Object.create({}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >{} : object >{} : {} var a = Object.create(null, {}); // any >a : any >Object.create(null, {}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >null : null >{} : {} var a = Object.create({ a: 1, b: "" }, {}); >a : any >Object.create({ a: 1, b: "" }, {}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >{ a: 1, b: "" } : { a: number; b: string; } >a : number >1 : 1 @@ -76,27 +76,27 @@ var a = Object.create({ a: 1, b: "" }, {}); var a = Object.create(union, {}); >a : any >Object.create(union, {}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >union : { a: number; b: string; } >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >{} : {} >{} : {} var a = Object.create({}, {}); >a : any >Object.create({}, {}) : any ->Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>Object.create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >Object : ObjectConstructor ->create : { (o: object): any; (o: object, properties: PropertyDescriptorMap): any; } +>create : { (o: object): any; (o: object, properties: PropertyDescriptorMap & ThisType): any; } >{} : object >{} : {} >{} : {} diff --git a/tests/baselines/reference/objectLitGetterSetter.types b/tests/baselines/reference/objectLitGetterSetter.types index 12801b65340bd..c2ce173e029de 100644 --- a/tests/baselines/reference/objectLitGetterSetter.types +++ b/tests/baselines/reference/objectLitGetterSetter.types @@ -5,9 +5,9 @@ Object.defineProperty(obj, "accProperty", ({ >Object.defineProperty(obj, "accProperty", ({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } })) : any ->Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any +>Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any >Object : ObjectConstructor ->defineProperty : (o: any, p: string, attributes: PropertyDescriptor) => any +>defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any >obj : {} >"accProperty" : "accProperty" >({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } }) : PropertyDescriptor