From 2a20e915e8850a47e059f5c1d12f866394ebd5e8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 18 Jan 2016 16:58:09 -0800 Subject: [PATCH] Allow assignments to readonly properties in constructors --- src/compiler/checker.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75751b45458..9fcf951ce83 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10366,6 +10366,17 @@ namespace ts { return true; } + function isReferenceWithinOwnConstructor(expr: Expression, symbol: Symbol): boolean { + // Allow assignments to readonly properties or methods (but not readonly accessors) within constructors + // of the same class declaration. + if ((expr.kind === SyntaxKind.PropertyAccessExpression || expr.kind === SyntaxKind.ElementAccessExpression) && + (expr as PropertyAccessExpression | ElementAccessExpression).expression.kind === SyntaxKind.ThisKeyword && + symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { + const func = getContainingFunction(expr); + return func && func.kind === SyntaxKind.Constructor && func.parent === symbol.valueDeclaration.parent; + } + } + function isReadonlySymbol(symbol: Symbol): boolean { if (symbol.flags & (SymbolFlags.Property | SymbolFlags.Method)) { return symbol === undefinedSymbol || (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Readonly) !== 0; @@ -10400,7 +10411,7 @@ namespace ts { error(expr, invalidReferenceMessage); return false; } - if (isReadonlySymbol(symbol) || isConstantSymbol(symbol)) { + if (isConstantSymbol(symbol) || (isReadonlySymbol(symbol) && !isReferenceWithinOwnConstructor(expr, symbol))) { error(expr, constantVariableMessage); return false; }