@@ -197,6 +197,7 @@ namespace ts {
197197 let globalNumberType: ObjectType;
198198 let globalBooleanType: ObjectType;
199199 let globalRegExpType: ObjectType;
200+ let globalThisType: GenericType;
200201 let anyArrayType: Type;
201202 let autoArrayType: Type;
202203 let anyReadonlyArrayType: Type;
@@ -5802,6 +5803,11 @@ namespace ts {
58025803 return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), arity);
58035804 }
58045805
5806+ function getGlobalTypeOrUndefined(name: string, arity = 0): ObjectType {
5807+ const symbol = getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined);
5808+ return symbol && <GenericType>getTypeOfGlobalSymbol(symbol, arity);
5809+ }
5810+
58055811 /**
58065812 * Returns a type that is inside a namespace at the global scope, e.g.
58075813 * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type
@@ -11180,6 +11186,22 @@ namespace ts {
1118011186 }
1118111187 }
1118211188
11189+ function getContainingObjectLiteral(func: FunctionLikeDeclaration) {
11190+ return func.kind === SyntaxKind.MethodDeclaration && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? <ObjectLiteralExpression>func.parent :
11191+ func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? <ObjectLiteralExpression>func.parent.parent :
11192+ undefined;
11193+ }
11194+
11195+ function getThisTypeArgument(type: Type): Type {
11196+ return getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).target === globalThisType ? (<TypeReference>type).typeArguments[0] : undefined;
11197+ }
11198+
11199+ function getThisTypeFromContextualType(type: Type): Type {
11200+ return applyToContextualType(type, t => {
11201+ return t.flags & TypeFlags.Intersection ? forEach((<IntersectionType>t).types, getThisTypeArgument) : getThisTypeArgument(t);
11202+ });
11203+ }
11204+
1118311205 function getContextualThisParameterType(func: FunctionLikeDeclaration): Type {
1118411206 if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
1118511207 const contextualSignature = getContextualSignature(func);
@@ -11189,17 +11211,24 @@ namespace ts {
1118911211 return getTypeOfSymbol(thisParameter);
1119011212 }
1119111213 }
11192- if (isObjectLiteralMethod(func)) {
11193- // For methods in an object literal, look for a '__this__' property in the contextual
11194- // type for the object literal. If one exists, remove 'undefined' from the type of that
11195- // property and report it as the contextual type for 'this' in the method.
11196- const objectLiteral = <ObjectLiteralExpression>func.parent;
11197- const type = getApparentTypeOfContextualType(objectLiteral);
11198- if (type) {
11199- const propertyType = getTypeOfPropertyOfContextualType(type, "___this__");
11200- if (propertyType) {
11201- return getNonNullableType(propertyType);
11214+ const containingLiteral = getContainingObjectLiteral(func);
11215+ if (containingLiteral) {
11216+ // We have an object literal method. Check if the containing object literal has a contextual type
11217+ // and if that contextual type is or includes a ThisType<T>. If so, T is the contextual type for
11218+ // 'this'. We continue looking in any directly enclosing object literals.
11219+ let objectLiteral = containingLiteral;
11220+ while (true) {
11221+ const type = getApparentTypeOfContextualType(objectLiteral);
11222+ if (type) {
11223+ const thisType = getThisTypeFromContextualType(type);
11224+ if (thisType) {
11225+ return thisType;
11226+ }
11227+ }
11228+ if (objectLiteral.parent.kind !== SyntaxKind.PropertyAssignment) {
11229+ break;
1120211230 }
11231+ objectLiteral = <ObjectLiteralExpression>objectLiteral.parent.parent;
1120311232 }
1120411233 }
1120511234 }
@@ -21175,9 +21204,9 @@ namespace ts {
2117521204 anyArrayType = createArrayType(anyType);
2117621205 autoArrayType = createArrayType(autoType);
2117721206
21178- const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
21179- globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
21207+ globalReadonlyArrayType = <GenericType>getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1);
2118021208 anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
21209+ globalThisType = <GenericType>getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
2118121210 }
2118221211
2118321212 function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
0 commit comments