diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d26da9bcbf082..7389765cce23b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -889,7 +889,7 @@ namespace ts { return isDottedName(expr) || (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) || isBinaryExpression(expr) && expr.operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference(expr.right) - || isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) + || isElementAccessExpression(expr) && (isStringOrNumericLiteralLike(expr.argumentExpression) || isIdentifier(expr.argumentExpression)) && isNarrowableReference(expr.expression) || isAssignmentExpression(expr) && isNarrowableReference(expr.left); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 20078bc12d87a..74988bef8256f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22358,9 +22358,10 @@ namespace ts { return isMatchingReference((source as NonNullExpression | ParenthesizedExpression).expression, target); case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: - return isAccessExpression(target) && - getAccessedPropertyName(source as AccessExpression) === getAccessedPropertyName(target) && - isMatchingReference((source as AccessExpression).expression, target.expression); + const sourcePropertyName = getAccessedPropertyName(source as AccessExpression); + const targetPropertyName = isAccessExpression(target) ? getAccessedPropertyName(target) : undefined; + return sourcePropertyName !== undefined && targetPropertyName !== undefined && targetPropertyName === sourcePropertyName && + isMatchingReference((source as AccessExpression).expression, (target as AccessExpression).expression); case SyntaxKind.QualifiedName: return isAccessExpression(target) && (source as QualifiedName).right.escapedText === getAccessedPropertyName(target) && @@ -22396,11 +22397,38 @@ namespace ts { } function getAccessedPropertyName(access: AccessExpression | BindingElement): __String | undefined { - let propertyName; - return access.kind === SyntaxKind.PropertyAccessExpression ? access.name.escapedText : - access.kind === SyntaxKind.ElementAccessExpression && isStringOrNumericLiteralLike(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) : - access.kind === SyntaxKind.BindingElement && (propertyName = getDestructuringPropertyName(access)) ? escapeLeadingUnderscores(propertyName) : - undefined; + if (isPropertyAccessExpression(access)) { + return access.name.escapedText; + } + if (isElementAccessExpression(access)) { + return tryGetElementAccessExpressionName(access); + } + if (isBindingElement(access)) { + const name = getDestructuringPropertyName(access); + return name ? escapeLeadingUnderscores(name) : undefined; + } + return undefined; + } + + function tryGetElementAccessExpressionName(node: ElementAccessExpression) { + if (isStringOrNumericLiteralLike(node.argumentExpression)) { + return escapeLeadingUnderscores(node.argumentExpression.text); + } + if (isIdentifier(node.argumentExpression)) { + const symbol = getResolvedSymbol(node.argumentExpression); + if (!isConstVariable(symbol)) return undefined; + + const declaration = symbol.valueDeclaration; + if (!(declaration && hasOnlyExpressionInitializer(declaration))) return undefined; + + const initializer = getEffectiveInitializer(declaration); + if (initializer === undefined) return undefined; + + const type = getTypeOfExpression(initializer); + return type.flags & TypeFlags.UniqueESSymbol ? (type as UniqueESSymbolType).escapedName : + type.flags & TypeFlags.StringOrNumberLiteral ? escapeLeadingUnderscores("" + (type as StringLiteralType | NumberLiteralType).value) : undefined; + } + return undefined; } function containsMatchingReference(source: Node, target: Node) { @@ -38598,7 +38626,7 @@ namespace ts { } if (!isStatic(member) && isPropertyWithoutInitializer(member)) { const propName = (member as PropertyDeclaration).name; - if (isIdentifier(propName) || isPrivateIdentifier(propName)) { + if (isIdentifier(propName) || isPrivateIdentifier(propName) || isComputedPropertyName(propName)) { const type = getTypeOfSymbol(getSymbolOfNode(member)); if (!(type.flags & TypeFlags.AnyOrUnknown || getFalsyFlags(type) & TypeFlags.Undefined)) { if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) { @@ -38634,8 +38662,10 @@ namespace ts { return false; } - function isPropertyInitializedInConstructor(propName: Identifier | PrivateIdentifier, propType: Type, constructor: ConstructorDeclaration) { - const reference = factory.createPropertyAccessExpression(factory.createThis(), propName); + function isPropertyInitializedInConstructor(propName: Identifier | PrivateIdentifier | ComputedPropertyName, propType: Type, constructor: ConstructorDeclaration) { + const reference = isComputedPropertyName(propName) + ? factory.createElementAccessExpression(factory.createThis(), propName.expression) + : factory.createPropertyAccessExpression(factory.createThis(), propName); setParent(reference.expression, reference); setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 118b72e252a94..98719a8d78f34 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2686,7 +2686,7 @@ namespace ts { function getPropFromRaw(prop: "files" | "include" | "exclude" | "references", validateElement: (value: unknown) => boolean, elementTypeName: string): PropOfRaw { if (hasProperty(raw, prop) && !isNullOrUndefined(raw[prop])) { if (isArray(raw[prop])) { - const result = raw[prop]; + const result = raw[prop] as T[]; if (!sourceFile && !every(result, validateElement)) { errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, prop, elementTypeName)); } diff --git a/tests/baselines/reference/incrementOnNullAssertion.types b/tests/baselines/reference/incrementOnNullAssertion.types index 0c7f5340b9f9a..199c4c87050f8 100644 --- a/tests/baselines/reference/incrementOnNullAssertion.types +++ b/tests/baselines/reference/incrementOnNullAssertion.types @@ -27,21 +27,21 @@ if (foo[x] === undefined) { } else { let nu = foo[x] ->nu : number | undefined ->foo[x] : number | undefined +>nu : number +>foo[x] : number >foo : Dictionary >x : "bar" let n = foo[x] ->n : number | undefined ->foo[x] : number | undefined +>n : number +>foo[x] : number >foo : Dictionary >x : "bar" foo[x]!++ >foo[x]!++ : number >foo[x]! : number ->foo[x] : number | undefined +>foo[x] : number >foo : Dictionary >x : "bar" } diff --git a/tests/baselines/reference/strictPropertyInitialization.errors.txt b/tests/baselines/reference/strictPropertyInitialization.errors.txt index aca8b44e0737c..208c0a32e4d1d 100644 --- a/tests/baselines/reference/strictPropertyInitialization.errors.txt +++ b/tests/baselines/reference/strictPropertyInitialization.errors.txt @@ -164,4 +164,19 @@ tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitial this.#b = someValue(); } } + + const a = 'a'; + const b = Symbol(); + + class C12 { + [a]: number; + [b]: number; + ['c']: number; + + constructor() { + this[a] = 1; + this[b] = 1; + this['c'] = 1; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/strictPropertyInitialization.js b/tests/baselines/reference/strictPropertyInitialization.js index 30867a3773de1..41760958edd1f 100644 --- a/tests/baselines/reference/strictPropertyInitialization.js +++ b/tests/baselines/reference/strictPropertyInitialization.js @@ -132,6 +132,21 @@ class C11 { this.#b = someValue(); } } + +const a = 'a'; +const b = Symbol(); + +class C12 { + [a]: number; + [b]: number; + ['c']: number; + + constructor() { + this[a] = 1; + this[b] = 1; + this['c'] = 1; + } +} //// [strictPropertyInitialization.js] @@ -235,6 +250,15 @@ class C11 { } } _C11_b = new WeakMap(); +const a = 'a'; +const b = Symbol(); +class C12 { + constructor() { + this[a] = 1; + this[b] = 1; + this['c'] = 1; + } +} //// [strictPropertyInitialization.d.ts] @@ -303,3 +327,11 @@ declare class C11 { a: number; constructor(); } +declare const a = "a"; +declare const b: unique symbol; +declare class C12 { + [a]: number; + [b]: number; + ['c']: number; + constructor(); +} diff --git a/tests/baselines/reference/strictPropertyInitialization.symbols b/tests/baselines/reference/strictPropertyInitialization.symbols index 2f1e4b9fbeceb..45e15f21403e5 100644 --- a/tests/baselines/reference/strictPropertyInitialization.symbols +++ b/tests/baselines/reference/strictPropertyInitialization.symbols @@ -311,3 +311,40 @@ class C11 { } } +const a = 'a'; +>a : Symbol(a, Decl(strictPropertyInitialization.ts, 134, 5)) + +const b = Symbol(); +>b : Symbol(b, Decl(strictPropertyInitialization.ts, 135, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +class C12 { +>C12 : Symbol(C12, Decl(strictPropertyInitialization.ts, 135, 19)) + + [a]: number; +>[a] : Symbol(C12[a], Decl(strictPropertyInitialization.ts, 137, 11)) +>a : Symbol(a, Decl(strictPropertyInitialization.ts, 134, 5)) + + [b]: number; +>[b] : Symbol(C12[b], Decl(strictPropertyInitialization.ts, 138, 16)) +>b : Symbol(b, Decl(strictPropertyInitialization.ts, 135, 5)) + + ['c']: number; +>['c'] : Symbol(C12['c'], Decl(strictPropertyInitialization.ts, 139, 16)) +>'c' : Symbol(C12['c'], Decl(strictPropertyInitialization.ts, 139, 16)) + + constructor() { + this[a] = 1; +>this : Symbol(C12, Decl(strictPropertyInitialization.ts, 135, 19)) +>a : Symbol(a, Decl(strictPropertyInitialization.ts, 134, 5)) + + this[b] = 1; +>this : Symbol(C12, Decl(strictPropertyInitialization.ts, 135, 19)) +>b : Symbol(b, Decl(strictPropertyInitialization.ts, 135, 5)) + + this['c'] = 1; +>this : Symbol(C12, Decl(strictPropertyInitialization.ts, 135, 19)) +>'c' : Symbol(C12['c'], Decl(strictPropertyInitialization.ts, 139, 16)) + } +} + diff --git a/tests/baselines/reference/strictPropertyInitialization.types b/tests/baselines/reference/strictPropertyInitialization.types index 8c7c20e613064..84d375c85157a 100644 --- a/tests/baselines/reference/strictPropertyInitialization.types +++ b/tests/baselines/reference/strictPropertyInitialization.types @@ -347,3 +347,51 @@ class C11 { } } +const a = 'a'; +>a : "a" +>'a' : "a" + +const b = Symbol(); +>b : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +class C12 { +>C12 : C12 + + [a]: number; +>[a] : number +>a : "a" + + [b]: number; +>[b] : number +>b : unique symbol + + ['c']: number; +>['c'] : number +>'c' : "c" + + constructor() { + this[a] = 1; +>this[a] = 1 : 1 +>this[a] : number +>this : this +>a : "a" +>1 : 1 + + this[b] = 1; +>this[b] = 1 : 1 +>this[b] : number +>this : this +>b : unique symbol +>1 : 1 + + this['c'] = 1; +>this['c'] = 1 : 1 +>this['c'] : number +>this : this +>'c' : "c" +>1 : 1 + } +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.js b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.js similarity index 95% rename from tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.js rename to tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.js index e951538563807..47616919e1c88 100644 --- a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.js +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.js @@ -1,4 +1,4 @@ -//// [typeGuardNarrowsIndexedAccessOfKnownProperty.ts] +//// [typeGuardNarrowsIndexedAccessOfKnownProperty1.ts] interface Square { ["dash-ok"]: "square"; ["square-size"]: number; @@ -80,7 +80,7 @@ export function g(pair: [number, string?]): string { } -//// [typeGuardNarrowsIndexedAccessOfKnownProperty.js] +//// [typeGuardNarrowsIndexedAccessOfKnownProperty1.js] "use strict"; exports.__esModule = true; exports.g = void 0; diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.symbols b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.symbols similarity index 73% rename from tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.symbols rename to tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.symbols index 3a8e434aa3c80..e60a512040069 100644 --- a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.symbols +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.symbols @@ -1,254 +1,254 @@ -=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty.ts === +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty1.ts === interface Square { ->Square : Symbol(Square, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 0, 0)) +>Square : Symbol(Square, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 0, 0)) ["dash-ok"]: "square"; ->["dash-ok"] : Symbol(Square["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 0, 18)) ->"dash-ok" : Symbol(Square["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 0, 18)) +>["dash-ok"] : Symbol(Square["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 0, 18)) +>"dash-ok" : Symbol(Square["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 0, 18)) ["square-size"]: number; ->["square-size"] : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 1, 26)) ->"square-size" : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 1, 26)) +>["square-size"] : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 1, 26)) +>"square-size" : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 1, 26)) } interface Rectangle { ->Rectangle : Symbol(Rectangle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 3, 1)) +>Rectangle : Symbol(Rectangle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 3, 1)) ["dash-ok"]: "rectangle"; ->["dash-ok"] : Symbol(Rectangle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 4, 22)) ->"dash-ok" : Symbol(Rectangle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 4, 22)) +>["dash-ok"] : Symbol(Rectangle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 4, 22)) +>"dash-ok" : Symbol(Rectangle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 4, 22)) width: number; ->width : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 5, 29)) +>width : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 5, 29)) height: number; ->height : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 6, 18)) +>height : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 6, 18)) } interface Circle { ->Circle : Symbol(Circle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 8, 1)) +>Circle : Symbol(Circle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 8, 1)) ["dash-ok"]: "circle"; ->["dash-ok"] : Symbol(Circle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 9, 19)) ->"dash-ok" : Symbol(Circle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 9, 19)) +>["dash-ok"] : Symbol(Circle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 9, 19)) +>"dash-ok" : Symbol(Circle["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 9, 19)) radius: number; ->radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) +>radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) } type Shape = Square | Rectangle | Circle; ->Shape : Symbol(Shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 12, 1)) ->Square : Symbol(Square, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 0, 0)) ->Rectangle : Symbol(Rectangle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 3, 1)) ->Circle : Symbol(Circle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 8, 1)) +>Shape : Symbol(Shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 12, 1)) +>Square : Symbol(Square, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 0, 0)) +>Rectangle : Symbol(Rectangle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 3, 1)) +>Circle : Symbol(Circle, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 8, 1)) interface Subshape { ->Subshape : Symbol(Subshape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 13, 42)) +>Subshape : Symbol(Subshape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 13, 42)) "0": { ->"0" : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) +>"0" : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) sub: { ->sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) +>sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) under: { ->under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) +>under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) shape: Shape; ->shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->Shape : Symbol(Shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 12, 1)) +>shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>Shape : Symbol(Shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 12, 1)) } } } } function area(s: Shape): number { ->area : Symbol(area, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 22, 1)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->Shape : Symbol(Shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 12, 1)) +>area : Symbol(area, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 22, 1)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>Shape : Symbol(Shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 12, 1)) switch(s['dash-ok']) { ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->'dash-ok' : Symbol(["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 0, 18), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 4, 22), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 9, 19)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>'dash-ok' : Symbol(["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 0, 18), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 4, 22), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 9, 19)) case "square": return s['square-size'] * s['square-size']; ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->'square-size' : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 1, 26)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->'square-size' : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 1, 26)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>'square-size' : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 1, 26)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>'square-size' : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 1, 26)) case "rectangle": return s.width * s['height']; ->s.width : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 5, 29)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->width : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 5, 29)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->'height' : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 6, 18)) +>s.width : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 5, 29)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>width : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 5, 29)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>'height' : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 6, 18)) case "circle": return Math.PI * s['radius'] * s.radius; >Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->'radius' : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) ->s.radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 23, 14)) ->radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>'radius' : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) +>s.radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 23, 14)) +>radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) } } function subarea(s: Subshape): number { ->subarea : Symbol(subarea, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 29, 1)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->Subshape : Symbol(Subshape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 13, 42)) +>subarea : Symbol(subarea, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 29, 1)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>Subshape : Symbol(Subshape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 13, 42)) switch(s[0]["sub"].under["shape"]["dash-ok"]) { ->s[0]["sub"].under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->"dash-ok" : Symbol(["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 0, 18), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 4, 22), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 9, 19)) +>s[0]["sub"].under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>"dash-ok" : Symbol(["dash-ok"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 0, 18), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 4, 22), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 9, 19)) case "square": return s[0].sub.under.shape["square-size"] * s[0].sub.under.shape["square-size"]; ->s[0].sub.under.shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->s[0].sub.under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->s[0].sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->"square-size" : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 1, 26)) ->s[0].sub.under.shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->s[0].sub.under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->s[0].sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->"square-size" : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 1, 26)) +>s[0].sub.under.shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>s[0].sub.under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>s[0].sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>"square-size" : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 1, 26)) +>s[0].sub.under.shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>s[0].sub.under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>s[0].sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>"square-size" : Symbol(Square["square-size"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 1, 26)) case "rectangle": return s[0]["sub"]["under"]["shape"]["width"] * s[0]["sub"]["under"]["shape"].height; ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->"under" : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->"width" : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 5, 29)) ->s[0]["sub"]["under"]["shape"].height : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 6, 18)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->"under" : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->height : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 6, 18)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>"under" : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>"width" : Symbol(Rectangle.width, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 5, 29)) +>s[0]["sub"]["under"]["shape"].height : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 6, 18)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>"under" : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>height : Symbol(Rectangle.height, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 6, 18)) case "circle": return Math.PI * s[0].sub.under["shape"].radius * s[0]["sub"].under.shape["radius"]; >Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) >Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) ->s[0].sub.under["shape"].radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) ->s[0].sub.under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->s[0].sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) ->s[0]["sub"].under.shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->s[0]["sub"].under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 30, 17)) ->0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 14, 20)) ->"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 15, 10)) ->under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 16, 14)) ->shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 17, 20)) ->"radius" : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 10, 26)) +>s[0].sub.under["shape"].radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) +>s[0].sub.under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>s[0].sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>sub : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>"shape" : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>radius : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) +>s[0]["sub"].under.shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>s[0]["sub"].under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>s : Symbol(s, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 30, 17)) +>0 : Symbol(Subshape["0"], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 14, 20)) +>"sub" : Symbol(sub, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 15, 10)) +>under : Symbol(under, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 16, 14)) +>shape : Symbol(shape, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 17, 20)) +>"radius" : Symbol(Circle.radius, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 10, 26)) } } interface X { ->X : Symbol(X, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 36, 1)) +>X : Symbol(X, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 36, 1)) 0: "xx", ->0 : Symbol(X[0], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 38, 13)) +>0 : Symbol(X[0], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 38, 13)) 1: number ->1 : Symbol(X[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 39, 12)) +>1 : Symbol(X[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 39, 12)) } interface Y { ->Y : Symbol(Y, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 41, 1)) +>Y : Symbol(Y, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 41, 1)) 0: "yy", ->0 : Symbol(Y[0], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 43, 13)) +>0 : Symbol(Y[0], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 43, 13)) 1: string ->1 : Symbol(Y[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 44, 12)) +>1 : Symbol(Y[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 44, 12)) } type A = ["aa", number]; ->A : Symbol(A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 46, 1)) +>A : Symbol(A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 46, 1)) type B = ["bb", string]; ->B : Symbol(B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 48, 24)) +>B : Symbol(B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 48, 24)) type Z = X | Y; ->Z : Symbol(Z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 49, 24)) ->X : Symbol(X, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 36, 1)) ->Y : Symbol(Y, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 41, 1)) +>Z : Symbol(Z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 49, 24)) +>X : Symbol(X, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 36, 1)) +>Y : Symbol(Y, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 41, 1)) type C = A | B; ->C : Symbol(C, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 51, 15)) ->A : Symbol(A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 46, 1)) ->B : Symbol(B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 48, 24)) +>C : Symbol(C, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 51, 15)) +>A : Symbol(A, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 46, 1)) +>B : Symbol(B, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 48, 24)) function check(z: Z, c: C) { ->check : Symbol(check, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 53, 15)) ->z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 15)) ->Z : Symbol(Z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 49, 24)) ->c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 20)) ->C : Symbol(C, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 51, 15)) +>check : Symbol(check, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 53, 15)) +>z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 15)) +>Z : Symbol(Z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 49, 24)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 20)) +>C : Symbol(C, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 51, 15)) z[0] // fine, typescript sees "xx" | "yy" ->z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 15)) ->0 : Symbol(0, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 38, 13), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 43, 13)) +>z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 15)) +>0 : Symbol(0, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 38, 13), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 43, 13)) switch (z[0]) { ->z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 15)) ->0 : Symbol(0, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 38, 13), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 43, 13)) +>z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 15)) +>0 : Symbol(0, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 38, 13), Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 43, 13)) case "xx": var xx: number = z[1] // should be number ->xx : Symbol(xx, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 59, 15)) ->z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 15)) ->1 : Symbol(X[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 39, 12)) +>xx : Symbol(xx, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 59, 15)) +>z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 15)) +>1 : Symbol(X[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 39, 12)) break; case "yy": var yy: string = z[1] // should be string ->yy : Symbol(yy, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 62, 15)) ->z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 15)) ->1 : Symbol(Y[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 44, 12)) +>yy : Symbol(yy, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 62, 15)) +>z : Symbol(z, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 15)) +>1 : Symbol(Y[1], Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 44, 12)) break; } c[0] // fine, typescript sees "xx" | "yy" ->c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 20)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 20)) >0 : Symbol(0) switch (c[0]) { ->c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 20)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 20)) >0 : Symbol(0) case "aa": var aa: number = c[1] // should be number ->aa : Symbol(aa, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 68, 15)) ->c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 20)) +>aa : Symbol(aa, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 68, 15)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 20)) >1 : Symbol(1) break; case "bb": var bb: string = c[1] // should be string ->bb : Symbol(bb, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 71, 15)) ->c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 55, 20)) +>bb : Symbol(bb, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 71, 15)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 55, 20)) >1 : Symbol(1) break; @@ -256,13 +256,13 @@ function check(z: Z, c: C) { } export function g(pair: [number, string?]): string { ->g : Symbol(g, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 74, 1)) ->pair : Symbol(pair, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 76, 18)) +>g : Symbol(g, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 74, 1)) +>pair : Symbol(pair, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 76, 18)) return pair[1] ? pair[1] : 'nope'; ->pair : Symbol(pair, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 76, 18)) +>pair : Symbol(pair, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 76, 18)) >1 : Symbol(1) ->pair : Symbol(pair, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty.ts, 76, 18)) +>pair : Symbol(pair, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty1.ts, 76, 18)) >1 : Symbol(1) } diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.types similarity index 95% rename from tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types rename to tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.types index f88376b118fb0..ee4fc6c2ec9c8 100644 --- a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty1.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty.ts === +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty1.ts === interface Square { ["dash-ok"]: "square"; >["dash-ok"] : "square" diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.js b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.js new file mode 100644 index 0000000000000..1c539d280e132 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.js @@ -0,0 +1,18 @@ +//// [typeGuardNarrowsIndexedAccessOfKnownProperty2.ts] +const foo: { key?: number } = {}; +const key = 'key' as const; + +if (foo[key]) { + foo[key]; // number + foo.key; // number +} + + +//// [typeGuardNarrowsIndexedAccessOfKnownProperty2.js] +"use strict"; +var foo = {}; +var key = 'key'; +if (foo[key]) { + foo[key]; // number + foo.key; // number +} diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.symbols b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.symbols new file mode 100644 index 0000000000000..b0ac52f071476 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty2.ts === +const foo: { key?: number } = {}; +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 5)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 12)) + +const key = 'key' as const; +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 1, 5)) +>const : Symbol(const) + +if (foo[key]) { +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 5)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 1, 5)) + + foo[key]; // number +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 5)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 1, 5)) + + foo.key; // number +>foo.key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 12)) +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 5)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty2.ts, 0, 12)) +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.types b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.types new file mode 100644 index 0000000000000..656540534e4f6 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty2.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty2.ts === +const foo: { key?: number } = {}; +>foo : { key?: number | undefined; } +>key : number | undefined +>{} : {} + +const key = 'key' as const; +>key : "key" +>'key' as const : "key" +>'key' : "key" + +if (foo[key]) { +>foo[key] : number | undefined +>foo : { key?: number | undefined; } +>key : "key" + + foo[key]; // number +>foo[key] : number +>foo : { key?: number | undefined; } +>key : "key" + + foo.key; // number +>foo.key : number +>foo : { key?: number | undefined; } +>key : number +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.js b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.js new file mode 100644 index 0000000000000..cae5cb742ab2e --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.js @@ -0,0 +1,18 @@ +//// [typeGuardNarrowsIndexedAccessOfKnownProperty3.ts] +type Foo = (number | undefined)[] | undefined; + +const foo: Foo = [1, 2, 3]; +const index = 1; + +if (foo !== undefined && foo[index] !== undefined && foo[index] >= 0) { + foo[index] // number +} + + +//// [typeGuardNarrowsIndexedAccessOfKnownProperty3.js] +"use strict"; +var foo = [1, 2, 3]; +var index = 1; +if (foo !== undefined && foo[index] !== undefined && foo[index] >= 0) { + foo[index]; // number +} diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.symbols b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.symbols new file mode 100644 index 0000000000000..06506802bdf2a --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.symbols @@ -0,0 +1,25 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty3.ts === +type Foo = (number | undefined)[] | undefined; +>Foo : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 0, 0)) + +const foo: Foo = [1, 2, 3]; +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 2, 5)) +>Foo : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 0, 0)) + +const index = 1; +>index : Symbol(index, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 3, 5)) + +if (foo !== undefined && foo[index] !== undefined && foo[index] >= 0) { +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 2, 5)) +>undefined : Symbol(undefined) +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 2, 5)) +>index : Symbol(index, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 3, 5)) +>undefined : Symbol(undefined) +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 2, 5)) +>index : Symbol(index, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 3, 5)) + + foo[index] // number +>foo : Symbol(foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 2, 5)) +>index : Symbol(index, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty3.ts, 3, 5)) +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.types b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.types new file mode 100644 index 0000000000000..b4c751d074398 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty3.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty3.ts === +type Foo = (number | undefined)[] | undefined; +>Foo : Foo + +const foo: Foo = [1, 2, 3]; +>foo : Foo +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 + +const index = 1; +>index : 1 +>1 : 1 + +if (foo !== undefined && foo[index] !== undefined && foo[index] >= 0) { +>foo !== undefined && foo[index] !== undefined && foo[index] >= 0 : boolean +>foo !== undefined && foo[index] !== undefined : boolean +>foo !== undefined : boolean +>foo : (number | undefined)[] +>undefined : undefined +>foo[index] !== undefined : boolean +>foo[index] : number | undefined +>foo : (number | undefined)[] +>index : 1 +>undefined : undefined +>foo[index] >= 0 : boolean +>foo[index] : number +>foo : (number | undefined)[] +>index : 1 +>0 : 0 + + foo[index] // number +>foo[index] : number +>foo : (number | undefined)[] +>index : 1 +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.js b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.js new file mode 100644 index 0000000000000..9214cf42de73b --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.js @@ -0,0 +1,28 @@ +//// [typeGuardNarrowsIndexedAccessOfKnownProperty4.ts] +class Foo { + x: number | undefined; + + constructor() { + this.x = 5; + + this.x; // number + this['x']; // number + + const key = 'x'; + this[key]; // number + } +} + + +//// [typeGuardNarrowsIndexedAccessOfKnownProperty4.js] +"use strict"; +var Foo = /** @class */ (function () { + function Foo() { + this.x = 5; + this.x; // number + this['x']; // number + var key = 'x'; + this[key]; // number + } + return Foo; +}()); diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.symbols b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.symbols new file mode 100644 index 0000000000000..5bbfcf72179b4 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty4.ts === +class Foo { +>Foo : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 0)) + + x: number | undefined; +>x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 11)) + + constructor() { + this.x = 5; +>this.x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 11)) +>this : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 0)) +>x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 11)) + + this.x; // number +>this.x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 11)) +>this : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 0)) +>x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 11)) + + this['x']; // number +>this : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 0)) +>'x' : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 11)) + + const key = 'x'; +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 9, 13)) + + this[key]; // number +>this : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 0, 0)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty4.ts, 9, 13)) + } +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.types b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.types new file mode 100644 index 0000000000000..f7a96a1e72221 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty4.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty4.ts === +class Foo { +>Foo : Foo + + x: number | undefined; +>x : number | undefined + + constructor() { + this.x = 5; +>this.x = 5 : 5 +>this.x : number | undefined +>this : this +>x : number | undefined +>5 : 5 + + this.x; // number +>this.x : number +>this : this +>x : number + + this['x']; // number +>this['x'] : number +>this : this +>'x' : "x" + + const key = 'x'; +>key : "x" +>'x' : "x" + + this[key]; // number +>this[key] : number +>this : this +>key : "x" + } +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.js b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.js new file mode 100644 index 0000000000000..a055fb5bceb27 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.js @@ -0,0 +1,40 @@ +//// [typeGuardNarrowsIndexedAccessOfKnownProperty5.ts] +const a: { key?: { x?: number } } = {}; +const aIndex = "key"; +if (a[aIndex] && a[aIndex].x) { + a[aIndex].x // number +} + +const b: { key: { x?: number } } = { key: {} }; +const bIndex = "key"; +if (b[bIndex].x) { + b[bIndex].x // number +} + +interface Foo { + x: number | undefined; +} +const c: Foo[] = []; +const cIndex = 1; +if (c[cIndex].x) { + c[cIndex].x // number +} + + +//// [typeGuardNarrowsIndexedAccessOfKnownProperty5.js] +"use strict"; +var a = {}; +var aIndex = "key"; +if (a[aIndex] && a[aIndex].x) { + a[aIndex].x; // number +} +var b = { key: {} }; +var bIndex = "key"; +if (b[bIndex].x) { + b[bIndex].x; // number +} +var c = []; +var cIndex = 1; +if (c[cIndex].x) { + c[cIndex].x; // number +} diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.symbols b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.symbols new file mode 100644 index 0000000000000..fdaca0a4b2460 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.symbols @@ -0,0 +1,72 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty5.ts === +const a: { key?: { x?: number } } = {}; +>a : Symbol(a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 5)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 10)) +>x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 18)) + +const aIndex = "key"; +>aIndex : Symbol(aIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 1, 5)) + +if (a[aIndex] && a[aIndex].x) { +>a : Symbol(a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 5)) +>aIndex : Symbol(aIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 1, 5)) +>a[aIndex].x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 18)) +>a : Symbol(a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 5)) +>aIndex : Symbol(aIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 1, 5)) +>x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 18)) + + a[aIndex].x // number +>a[aIndex].x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 18)) +>a : Symbol(a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 5)) +>aIndex : Symbol(aIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 1, 5)) +>x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 0, 18)) +} + +const b: { key: { x?: number } } = { key: {} }; +>b : Symbol(b, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 5)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 10)) +>x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 17)) +>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 36)) + +const bIndex = "key"; +>bIndex : Symbol(bIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 7, 5)) + +if (b[bIndex].x) { +>b[bIndex].x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 17)) +>b : Symbol(b, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 5)) +>bIndex : Symbol(bIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 7, 5)) +>x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 17)) + + b[bIndex].x // number +>b[bIndex].x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 17)) +>b : Symbol(b, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 5)) +>bIndex : Symbol(bIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 7, 5)) +>x : Symbol(x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 6, 17)) +} + +interface Foo { +>Foo : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 10, 1)) + + x: number | undefined; +>x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 12, 15)) +} +const c: Foo[] = []; +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 15, 5)) +>Foo : Symbol(Foo, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 10, 1)) + +const cIndex = 1; +>cIndex : Symbol(cIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 16, 5)) + +if (c[cIndex].x) { +>c[cIndex].x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 12, 15)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 15, 5)) +>cIndex : Symbol(cIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 16, 5)) +>x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 12, 15)) + + c[cIndex].x // number +>c[cIndex].x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 12, 15)) +>c : Symbol(c, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 15, 5)) +>cIndex : Symbol(cIndex, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 16, 5)) +>x : Symbol(Foo.x, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty5.ts, 12, 15)) +} + diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.types b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.types new file mode 100644 index 0000000000000..b202ee18f9173 --- /dev/null +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty5.types @@ -0,0 +1,84 @@ +=== tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty5.ts === +const a: { key?: { x?: number } } = {}; +>a : { key?: { x?: number | undefined; } | undefined; } +>key : { x?: number | undefined; } | undefined +>x : number | undefined +>{} : {} + +const aIndex = "key"; +>aIndex : "key" +>"key" : "key" + +if (a[aIndex] && a[aIndex].x) { +>a[aIndex] && a[aIndex].x : number | undefined +>a[aIndex] : { x?: number | undefined; } | undefined +>a : { key?: { x?: number | undefined; } | undefined; } +>aIndex : "key" +>a[aIndex].x : number | undefined +>a[aIndex] : { x?: number | undefined; } +>a : { key?: { x?: number | undefined; } | undefined; } +>aIndex : "key" +>x : number | undefined + + a[aIndex].x // number +>a[aIndex].x : number +>a[aIndex] : { x?: number | undefined; } +>a : { key?: { x?: number | undefined; } | undefined; } +>aIndex : "key" +>x : number +} + +const b: { key: { x?: number } } = { key: {} }; +>b : { key: { x?: number;}; } +>key : { x?: number | undefined; } +>x : number | undefined +>{ key: {} } : { key: {}; } +>key : {} +>{} : {} + +const bIndex = "key"; +>bIndex : "key" +>"key" : "key" + +if (b[bIndex].x) { +>b[bIndex].x : number | undefined +>b[bIndex] : { x?: number | undefined; } +>b : { key: { x?: number | undefined; }; } +>bIndex : "key" +>x : number | undefined + + b[bIndex].x // number +>b[bIndex].x : number +>b[bIndex] : { x?: number | undefined; } +>b : { key: { x?: number | undefined; }; } +>bIndex : "key" +>x : number +} + +interface Foo { + x: number | undefined; +>x : number | undefined +} +const c: Foo[] = []; +>c : Foo[] +>[] : never[] + +const cIndex = 1; +>cIndex : 1 +>1 : 1 + +if (c[cIndex].x) { +>c[cIndex].x : number | undefined +>c[cIndex] : Foo +>c : Foo[] +>cIndex : 1 +>x : number | undefined + + c[cIndex].x // number +>c[cIndex].x : number +>c[cIndex] : Foo +>c : Foo[] +>cIndex : 1 +>x : number +} + diff --git a/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty.ts b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty1.ts similarity index 100% rename from tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty.ts rename to tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty1.ts diff --git a/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty2.ts b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty2.ts new file mode 100644 index 0000000000000..2dd12edde864e --- /dev/null +++ b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty2.ts @@ -0,0 +1,9 @@ +// @strict: true + +const foo: { key?: number } = {}; +const key = 'key' as const; + +if (foo[key]) { + foo[key]; // number + foo.key; // number +} diff --git a/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty3.ts b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty3.ts new file mode 100644 index 0000000000000..7b92297fb48c5 --- /dev/null +++ b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty3.ts @@ -0,0 +1,10 @@ +// @strict: true + +type Foo = (number | undefined)[] | undefined; + +const foo: Foo = [1, 2, 3]; +const index = 1; + +if (foo !== undefined && foo[index] !== undefined && foo[index] >= 0) { + foo[index] // number +} diff --git a/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty4.ts b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty4.ts new file mode 100644 index 0000000000000..aa2782c493268 --- /dev/null +++ b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty4.ts @@ -0,0 +1,15 @@ +// @strict: true + +class Foo { + x: number | undefined; + + constructor() { + this.x = 5; + + this.x; // number + this['x']; // number + + const key = 'x'; + this[key]; // number + } +} diff --git a/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty5.ts b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty5.ts new file mode 100644 index 0000000000000..efb553acd7a5b --- /dev/null +++ b/tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty5.ts @@ -0,0 +1,22 @@ +// @strict: true + +const a: { key?: { x?: number } } = {}; +const aIndex = "key"; +if (a[aIndex] && a[aIndex].x) { + a[aIndex].x // number +} + +const b: { key: { x?: number } } = { key: {} }; +const bIndex = "key"; +if (b[bIndex].x) { + b[bIndex].x // number +} + +interface Foo { + x: number | undefined; +} +const c: Foo[] = []; +const cIndex = 1; +if (c[cIndex].x) { + c[cIndex].x // number +} diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts index 7b0da5059b30a..3caf731626494 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/strictPropertyInitialization.ts @@ -1,5 +1,5 @@ // @strict: true -// @target:es2015 +// @target: es2015 // @declaration: true // Properties with non-undefined types require initialization @@ -135,3 +135,18 @@ class C11 { this.#b = someValue(); } } + +const a = 'a'; +const b = Symbol(); + +class C12 { + [a]: number; + [b]: number; + ['c']: number; + + constructor() { + this[a] = 1; + this[b] = 1; + this['c'] = 1; + } +}