diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d825b0d971758..cd4243f8550b3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14941,7 +14941,7 @@ namespace ts { // except for the special case of Javascript declarations of the form `namespace.prop = namespace.prop || {}` const type = getContextualType(binaryExpression); return !type && node === right && !getDeclaredJavascriptInitializer(binaryExpression.parent) && !getAssignedJavascriptInitializer(binaryExpression) ? - getTypeOfExpression(left, /*cache*/ true) : type; + getTypeOfExpression(left) : type; case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.CommaToken: return node === right ? getContextualType(binaryExpression) : undefined; diff --git a/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.js b/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.js new file mode 100644 index 0000000000000..8e600761d2c7f --- /dev/null +++ b/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.js @@ -0,0 +1,48 @@ +//// [contextualExpressionTypecheckingDoesntBlowStack.ts] +// repro for: https://github.com/Microsoft/TypeScript/issues/23661 +export interface IValidationError { + message: string; +} + +export default class Operation { + validateParameters(parameterValues: any) : IValidationError[] | null { + let result: IValidationError[] | null = null; + for(const parameterLocation of Object.keys(parameterValues)) { + const parameter: any = (this as any).getParameter();; + const values = (this as any).getValues(); + + const innerResult = parameter.validate(values[parameter.oaParameter.name]); + if(innerResult && innerResult.length > 0) { + // Commenting out this line will fix the problem. + result = (result || []).concat(innerResult); + } + } + + return result; + } +} + +//// [contextualExpressionTypecheckingDoesntBlowStack.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Operation = /** @class */ (function () { + function Operation() { + } + Operation.prototype.validateParameters = function (parameterValues) { + var result = null; + for (var _i = 0, _a = Object.keys(parameterValues); _i < _a.length; _i++) { + var parameterLocation = _a[_i]; + var parameter = this.getParameter(); + ; + var values = this.getValues(); + var innerResult = parameter.validate(values[parameter.oaParameter.name]); + if (innerResult && innerResult.length > 0) { + // Commenting out this line will fix the problem. + result = (result || []).concat(innerResult); + } + } + return result; + }; + return Operation; +}()); +exports.default = Operation; diff --git a/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.symbols b/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.symbols new file mode 100644 index 0000000000000..fc44c97996c92 --- /dev/null +++ b/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.symbols @@ -0,0 +1,60 @@ +=== tests/cases/compiler/contextualExpressionTypecheckingDoesntBlowStack.ts === +// repro for: https://github.com/Microsoft/TypeScript/issues/23661 +export interface IValidationError { +>IValidationError : Symbol(IValidationError, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 0, 0)) + + message: string; +>message : Symbol(IValidationError.message, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 1, 35)) +} + +export default class Operation { +>Operation : Symbol(Operation, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 3, 1)) + + validateParameters(parameterValues: any) : IValidationError[] | null { +>validateParameters : Symbol(Operation.validateParameters, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 5, 32)) +>parameterValues : Symbol(parameterValues, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 6, 23)) +>IValidationError : Symbol(IValidationError, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 0, 0)) + + let result: IValidationError[] | null = null; +>result : Symbol(result, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 7, 11)) +>IValidationError : Symbol(IValidationError, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 0, 0)) + + for(const parameterLocation of Object.keys(parameterValues)) { +>parameterLocation : Symbol(parameterLocation, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 8, 17)) +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>parameterValues : Symbol(parameterValues, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 6, 23)) + + const parameter: any = (this as any).getParameter();; +>parameter : Symbol(parameter, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 9, 17)) +>this : Symbol(Operation, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 3, 1)) + + const values = (this as any).getValues(); +>values : Symbol(values, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 10, 17)) +>this : Symbol(Operation, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 3, 1)) + + const innerResult = parameter.validate(values[parameter.oaParameter.name]); +>innerResult : Symbol(innerResult, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 12, 17)) +>parameter : Symbol(parameter, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 9, 17)) +>values : Symbol(values, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 10, 17)) +>parameter : Symbol(parameter, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 9, 17)) + + if(innerResult && innerResult.length > 0) { +>innerResult : Symbol(innerResult, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 12, 17)) +>innerResult : Symbol(innerResult, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 12, 17)) + + // Commenting out this line will fix the problem. + result = (result || []).concat(innerResult); +>result : Symbol(result, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 7, 11)) +>(result || []).concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>result : Symbol(result, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 7, 11)) +>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>innerResult : Symbol(innerResult, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 12, 17)) + } + } + + return result; +>result : Symbol(result, Decl(contextualExpressionTypecheckingDoesntBlowStack.ts, 7, 11)) + } +} diff --git a/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.types b/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.types new file mode 100644 index 0000000000000..5965a2c77430e --- /dev/null +++ b/tests/baselines/reference/contextualExpressionTypecheckingDoesntBlowStack.types @@ -0,0 +1,92 @@ +=== tests/cases/compiler/contextualExpressionTypecheckingDoesntBlowStack.ts === +// repro for: https://github.com/Microsoft/TypeScript/issues/23661 +export interface IValidationError { +>IValidationError : IValidationError + + message: string; +>message : string +} + +export default class Operation { +>Operation : Operation + + validateParameters(parameterValues: any) : IValidationError[] | null { +>validateParameters : (parameterValues: any) => IValidationError[] | null +>parameterValues : any +>IValidationError : IValidationError +>null : null + + let result: IValidationError[] | null = null; +>result : IValidationError[] | null +>IValidationError : IValidationError +>null : null +>null : null + + for(const parameterLocation of Object.keys(parameterValues)) { +>parameterLocation : string +>Object.keys(parameterValues) : string[] +>Object.keys : (o: {}) => string[] +>Object : ObjectConstructor +>keys : (o: {}) => string[] +>parameterValues : any + + const parameter: any = (this as any).getParameter();; +>parameter : any +>(this as any).getParameter() : any +>(this as any).getParameter : any +>(this as any) : any +>this as any : any +>this : this +>getParameter : any + + const values = (this as any).getValues(); +>values : any +>(this as any).getValues() : any +>(this as any).getValues : any +>(this as any) : any +>this as any : any +>this : this +>getValues : any + + const innerResult = parameter.validate(values[parameter.oaParameter.name]); +>innerResult : any +>parameter.validate(values[parameter.oaParameter.name]) : any +>parameter.validate : any +>parameter : any +>validate : any +>values[parameter.oaParameter.name] : any +>values : any +>parameter.oaParameter.name : any +>parameter.oaParameter : any +>parameter : any +>oaParameter : any +>name : any + + if(innerResult && innerResult.length > 0) { +>innerResult && innerResult.length > 0 : boolean +>innerResult : any +>innerResult.length > 0 : boolean +>innerResult.length : any +>innerResult : any +>length : any +>0 : 0 + + // Commenting out this line will fix the problem. + result = (result || []).concat(innerResult); +>result = (result || []).concat(innerResult) : IValidationError[] +>result : IValidationError[] | null +>(result || []).concat(innerResult) : IValidationError[] +>(result || []).concat : { (...items: ConcatArray[]): IValidationError[]; (...items: (IValidationError | ConcatArray)[]): IValidationError[]; } +>(result || []) : IValidationError[] +>result || [] : IValidationError[] +>result : IValidationError[] | null +>[] : never[] +>concat : { (...items: ConcatArray[]): IValidationError[]; (...items: (IValidationError | ConcatArray)[]): IValidationError[]; } +>innerResult : any + } + } + + return result; +>result : IValidationError[] | null + } +} diff --git a/tests/cases/compiler/contextualExpressionTypecheckingDoesntBlowStack.ts b/tests/cases/compiler/contextualExpressionTypecheckingDoesntBlowStack.ts new file mode 100644 index 0000000000000..9abff096a7631 --- /dev/null +++ b/tests/cases/compiler/contextualExpressionTypecheckingDoesntBlowStack.ts @@ -0,0 +1,26 @@ +// @target: es5 +// @lib: es6 +// @strict: true + +// repro for: https://github.com/Microsoft/TypeScript/issues/23661 +export interface IValidationError { + message: string; +} + +export default class Operation { + validateParameters(parameterValues: any) : IValidationError[] | null { + let result: IValidationError[] | null = null; + for(const parameterLocation of Object.keys(parameterValues)) { + const parameter: any = (this as any).getParameter();; + const values = (this as any).getValues(); + + const innerResult = parameter.validate(values[parameter.oaParameter.name]); + if(innerResult && innerResult.length > 0) { + // Commenting out this line will fix the problem. + result = (result || []).concat(innerResult); + } + } + + return result; + } +} \ No newline at end of file