diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8809c34d06053..0d42737bf4dca 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -905,6 +905,9 @@ namespace ts { function isNarrowingBinaryExpression(expr: BinaryExpression) { switch (expr.operatorToken.kind) { case SyntaxKind.EqualsToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: return containsNarrowableReference(expr.left); case SyntaxKind.EqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: @@ -1041,12 +1044,18 @@ namespace ts { } } + function isLogicalAssignmentExpression(node: Node) { + node = skipParentheses(node); + return isBinaryExpression(node) && isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind); + } + function isTopLevelLogicalExpression(node: Node): boolean { while (isParenthesizedExpression(node.parent) || isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.ExclamationToken) { node = node.parent; } return !isStatementCondition(node) && + !isLogicalAssignmentExpression(node.parent) && !isLogicalExpression(node.parent) && !(isOptionalChain(node.parent) && node.parent.expression === node); } @@ -1063,7 +1072,7 @@ namespace ts { function bindCondition(node: Expression | undefined, trueTarget: FlowLabel, falseTarget: FlowLabel) { doWithConditionalBranches(bind, node, trueTarget, falseTarget); - if (!node || !isLogicalExpression(node) && !(isOptionalChain(node) && isOutermostOptionalChain(node))) { + if (!node || !isLogicalAssignmentExpression(node) && !isLogicalExpression(node) && !(isOptionalChain(node) && isOutermostOptionalChain(node))) { addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); } @@ -1404,9 +1413,9 @@ namespace ts { } } - function bindLogicalExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) { + function bindLogicalLikeExpression(node: BinaryExpression, trueTarget: FlowLabel, falseTarget: FlowLabel) { const preRightLabel = createBranchLabel(); - if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { + if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || node.operatorToken.kind === SyntaxKind.AmpersandAmpersandEqualsToken) { bindCondition(node.left, preRightLabel, falseTarget); } else { @@ -1414,7 +1423,17 @@ namespace ts { } currentFlow = finishFlowLabel(preRightLabel); bind(node.operatorToken); - bindCondition(node.right, trueTarget, falseTarget); + + if (isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind)) { + doWithConditionalBranches(bind, node.right, trueTarget, falseTarget); + bindAssignmentTargetFlow(node.left); + + addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node)); + addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node)); + } + else { + bindCondition(node.right, trueTarget, falseTarget); + } } function bindPrefixUnaryExpressionFlow(node: PrefixUnaryExpression) { @@ -1500,14 +1519,15 @@ namespace ts { // TODO: bindLogicalExpression is recursive - if we want to handle deeply nested `&&` expressions // we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too // For now, though, since the common cases are chained `+`, leaving it recursive is fine - if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) { + if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken || + isLogicalOrCoalescingAssignmentOperator(operator)) { if (isTopLevelLogicalExpression(node)) { const postExpressionLabel = createBranchLabel(); - bindLogicalExpression(node, postExpressionLabel, postExpressionLabel); + bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel); currentFlow = finishFlowLabel(postExpressionLabel); } else { - bindLogicalExpression(node, currentTrueTarget!, currentFalseTarget!); + bindLogicalLikeExpression(node, currentTrueTarget!, currentFalseTarget!); } completeNode(); } @@ -3607,6 +3627,9 @@ namespace ts { if (operatorTokenKind === SyntaxKind.QuestionQuestionToken) { transformFlags |= TransformFlags.AssertES2020; } + else if (isLogicalOrCoalescingAssignmentOperator(operatorTokenKind)) { + transformFlags |= TransformFlags.AssertESNext; + } else if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ObjectLiteralExpression) { // Destructuring object assignments with are ES2015 syntax // and possibly ES2018 if they contain rest diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bd58c379eac9..a09a8a6a611f5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19832,6 +19832,9 @@ namespace ts { case SyntaxKind.BinaryExpression: switch ((node).operatorToken.kind) { case SyntaxKind.EqualsToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: return getReferenceCandidate((node).left); case SyntaxKind.CommaToken: return getReferenceCandidate((node).right); @@ -20806,6 +20809,9 @@ namespace ts { function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { switch (expr.operatorToken.kind) { case SyntaxKind.EqualsToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue); case SyntaxKind.EqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: @@ -22430,6 +22436,9 @@ namespace ts { const { left, operatorToken, right } = binaryExpression; switch (operatorToken.kind) { case SyntaxKind.EqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: if (node !== right) { return undefined; } @@ -28700,17 +28709,35 @@ namespace ts { case SyntaxKind.InKeyword: return checkInExpression(left, right, leftType, rightType); case SyntaxKind.AmpersandAmpersandToken: - return getTypeFacts(leftType) & TypeFacts.Truthy ? + case SyntaxKind.AmpersandAmpersandEqualsToken: { + const resultType = getTypeFacts(leftType) & TypeFacts.Truthy ? getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) : leftType; + if (operator === SyntaxKind.AmpersandAmpersandEqualsToken) { + checkAssignmentOperator(rightType); + } + return resultType; + } case SyntaxKind.BarBarToken: - return getTypeFacts(leftType) & TypeFacts.Falsy ? + case SyntaxKind.BarBarEqualsToken: { + const resultType = getTypeFacts(leftType) & TypeFacts.Falsy ? getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) : leftType; + if (operator === SyntaxKind.BarBarEqualsToken) { + checkAssignmentOperator(rightType); + } + return resultType; + } case SyntaxKind.QuestionQuestionToken: - return getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ? + case SyntaxKind.QuestionQuestionEqualsToken: { + const resultType = getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ? getUnionType([getNonNullableType(leftType), rightType], UnionReduction.Subtype) : leftType; + if (operator === SyntaxKind.QuestionQuestionEqualsToken) { + checkAssignmentOperator(rightType); + } + return resultType; + } case SyntaxKind.EqualsToken: const declKind = isBinaryExpression(left.parent) ? getAssignmentDeclarationKind(left.parent) : AssignmentDeclarationKind.None; checkAssignmentDeclaration(declKind, rightType); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index a4513e8cdf6df..27c88e8e13d84 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -208,6 +208,9 @@ namespace ts { "&=": SyntaxKind.AmpersandEqualsToken, "|=": SyntaxKind.BarEqualsToken, "^=": SyntaxKind.CaretEqualsToken, + "||=": SyntaxKind.BarBarEqualsToken, + "&&=": SyntaxKind.AmpersandAmpersandEqualsToken, + "??=": SyntaxKind.QuestionQuestionEqualsToken, "@": SyntaxKind.AtToken, "`": SyntaxKind.BacktickToken }); @@ -1667,6 +1670,9 @@ namespace ts { return token = SyntaxKind.PercentToken; case CharacterCodes.ampersand: if (text.charCodeAt(pos + 1) === CharacterCodes.ampersand) { + if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { + return pos += 3, token = SyntaxKind.AmpersandAmpersandEqualsToken; + } return pos += 2, token = SyntaxKind.AmpersandAmpersandToken; } if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { @@ -1928,15 +1934,16 @@ namespace ts { pos++; return token = SyntaxKind.GreaterThanToken; case CharacterCodes.question: - pos++; - if (text.charCodeAt(pos) === CharacterCodes.dot && !isDigit(text.charCodeAt(pos + 1))) { - pos++; - return token = SyntaxKind.QuestionDotToken; + if (text.charCodeAt(pos + 1) === CharacterCodes.dot && !isDigit(text.charCodeAt(pos + 2))) { + return pos += 2, token = SyntaxKind.QuestionDotToken; } - if (text.charCodeAt(pos) === CharacterCodes.question) { - pos++; - return token = SyntaxKind.QuestionQuestionToken; + if (text.charCodeAt(pos + 1) === CharacterCodes.question) { + if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { + return pos += 3, token = SyntaxKind.QuestionQuestionEqualsToken; + } + return pos += 2, token = SyntaxKind.QuestionQuestionToken; } + pos++; return token = SyntaxKind.QuestionToken; case CharacterCodes.openBracket: pos++; @@ -1965,6 +1972,9 @@ namespace ts { } if (text.charCodeAt(pos + 1) === CharacterCodes.bar) { + if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { + return pos += 3, token = SyntaxKind.BarBarEqualsToken; + } return pos += 2, token = SyntaxKind.BarBarToken; } if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { diff --git a/src/compiler/transformers/es2020.ts b/src/compiler/transformers/es2020.ts index 8cf3169752094..8e45fb38f60c8 100644 --- a/src/compiler/transformers/es2020.ts +++ b/src/compiler/transformers/es2020.ts @@ -73,7 +73,7 @@ namespace ts { let thisArg: Expression | undefined; if (captureThisArg) { - if (shouldCaptureInTempVariable(expression)) { + if (!isSimpleCopiableExpression(expression)) { thisArg = createTempVariable(hoistVariableDeclaration); expression = createAssignment(thisArg, expression); // if (inParameterInitializer) tempVariableInParameter = true; @@ -113,7 +113,7 @@ namespace ts { const leftThisArg = isSyntheticReference(left) ? left.thisArg : undefined; let leftExpression = isSyntheticReference(left) ? left.expression : left; let capturedLeft: Expression = leftExpression; - if (shouldCaptureInTempVariable(leftExpression)) { + if (!isSimpleCopiableExpression(leftExpression)) { capturedLeft = createTempVariable(hoistVariableDeclaration); leftExpression = createAssignment(capturedLeft, leftExpression); // if (inParameterInitializer) tempVariableInParameter = true; @@ -126,7 +126,7 @@ namespace ts { case SyntaxKind.PropertyAccessExpression: case SyntaxKind.ElementAccessExpression: if (i === chain.length - 1 && captureThisArg) { - if (shouldCaptureInTempVariable(rightExpression)) { + if (!isSimpleCopiableExpression(rightExpression)) { thisArg = createTempVariable(hoistVariableDeclaration); rightExpression = createAssignment(thisArg, rightExpression); // if (inParameterInitializer) tempVariableInParameter = true; @@ -184,7 +184,7 @@ namespace ts { function transformNullishCoalescingExpression(node: BinaryExpression) { let left = visitNode(node.left, visitor, isExpression); let right = left; - if (shouldCaptureInTempVariable(left)) { + if (!isSimpleCopiableExpression(left)) { right = createTempVariable(hoistVariableDeclaration); left = createAssignment(right, left); // if (inParameterInitializer) tempVariableInParameter = true; @@ -196,14 +196,6 @@ namespace ts { ); } - function shouldCaptureInTempVariable(expression: Expression): boolean { - // don't capture identifiers and `this` in a temporary variable - // `super` cannot be captured as it's no real variable - return !isIdentifier(expression) && - expression.kind !== SyntaxKind.ThisKeyword && - expression.kind !== SyntaxKind.SuperKeyword; - } - function visitDeleteExpression(node: DeleteExpression) { return isOptionalChain(skipParentheses(node.expression)) ? setOriginalNode(visitNonOptionalExpression(node.expression, /*captureThisArg*/ false, /*isDelete*/ true), node) diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index 80debb46f8a04..65bb1c1713743 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -1,6 +1,9 @@ /*@internal*/ namespace ts { export function transformESNext(context: TransformationContext) { + const { + hoistVariableDeclaration + } = context; return chainBundle(transformSourceFile); function transformSourceFile(node: SourceFile) { @@ -16,9 +19,63 @@ namespace ts { return node; } switch (node.kind) { + case SyntaxKind.BinaryExpression: + const binaryExpression = node; + if (isLogicalOrCoalescingAssignmentExpression(binaryExpression)) { + return transformLogicalAssignment(binaryExpression); + } + // falls through default: return visitEachChild(node, visitor, context); } } + + function transformLogicalAssignment(binaryExpression: AssignmentExpression>): VisitResult { + const operator = binaryExpression.operatorToken; + const nonAssignmentOperator = getNonAssignmentOperatorForCompoundAssignment(operator.kind); + let left = skipParentheses(visitNode(binaryExpression.left, visitor, isLeftHandSideExpression)); + let assignmentTarget = left; + const right = skipParentheses(visitNode(binaryExpression.right, visitor, isExpression)); + if (isAccessExpression(left)) { + const tempVariable = createTempVariable(hoistVariableDeclaration); + if (isPropertyAccessExpression(left)) { + assignmentTarget = createPropertyAccess( + tempVariable, + left.name + ); + left = createPropertyAccess( + createAssignment( + tempVariable, + left.expression + ), + left.name + ); + } + else { + assignmentTarget = createElementAccess( + tempVariable, + left.argumentExpression + ); + left = createElementAccess( + createAssignment( + tempVariable, + left.expression + ), + left.argumentExpression + ); + } + } + + return createBinary( + left, + nonAssignmentOperator, + createParen( + createAssignment( + assignmentTarget, + right + ) + ) + ); + } } } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 4a4dc05de76a7..94c734d12ae2c 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -259,7 +259,7 @@ namespace ts { && kind <= SyntaxKind.LastCompoundAssignment; } - export function getNonAssignmentOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): BitwiseOperatorOrHigher { + export function getNonAssignmentOperatorForCompoundAssignment(kind: CompoundAssignmentOperator): LogicalOperatorOrHigher | SyntaxKind.QuestionQuestionToken { switch (kind) { case SyntaxKind.PlusEqualsToken: return SyntaxKind.PlusToken; case SyntaxKind.MinusEqualsToken: return SyntaxKind.MinusToken; @@ -273,6 +273,10 @@ namespace ts { case SyntaxKind.AmpersandEqualsToken: return SyntaxKind.AmpersandToken; case SyntaxKind.BarEqualsToken: return SyntaxKind.BarToken; case SyntaxKind.CaretEqualsToken: return SyntaxKind.CaretToken; + case SyntaxKind.BarBarEqualsToken: return SyntaxKind.BarBarToken; + case SyntaxKind.AmpersandAmpersandEqualsToken: return SyntaxKind.AmpersandAmpersandToken; + case SyntaxKind.QuestionQuestionEqualsToken: return SyntaxKind.QuestionQuestionToken; + } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0c45dca9529fc..5845f8ff6538b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -203,6 +203,9 @@ namespace ts { GreaterThanGreaterThanGreaterThanEqualsToken, AmpersandEqualsToken, BarEqualsToken, + BarBarEqualsToken, + AmpersandAmpersandEqualsToken, + QuestionQuestionEqualsToken, CaretEqualsToken, // Identifiers and PrivateIdentifiers Identifier, @@ -1608,6 +1611,9 @@ namespace ts { | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken + | SyntaxKind.BarBarEqualsToken + | SyntaxKind.AmpersandAmpersandEqualsToken + | SyntaxKind.QuestionQuestionEqualsToken ; // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression @@ -1629,6 +1635,12 @@ namespace ts { | SyntaxKind.CommaToken ; + export type LogicalOrCoalescingAssignmentOperator + = SyntaxKind.AmpersandAmpersandEqualsToken + | SyntaxKind.BarBarEqualsToken + | SyntaxKind.QuestionQuestionEqualsToken + ; + export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 17ce0562122e0..014cd58d1b353 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2594,7 +2594,7 @@ namespace ts { switch (parent.kind) { case SyntaxKind.BinaryExpression: const binaryOperator = (parent).operatorToken.kind; - return isAssignmentOperator(binaryOperator) && (parent).left === node ? + return isAssignmentOperator(binaryOperator) && !isLogicalOrCoalescingAssignmentOperator(binaryOperator) && (parent).left === node ? binaryOperator === SyntaxKind.EqualsToken ? AssignmentKind.Definite : AssignmentKind.Compound : AssignmentKind.None; case SyntaxKind.PrefixUnaryExpression: @@ -3220,6 +3220,9 @@ namespace ts { case SyntaxKind.AmpersandEqualsToken: case SyntaxKind.CaretEqualsToken: case SyntaxKind.BarEqualsToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: return Associativity.Right; } } @@ -3276,6 +3279,9 @@ namespace ts { case SyntaxKind.AmpersandEqualsToken: case SyntaxKind.CaretEqualsToken: case SyntaxKind.BarEqualsToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: return 3; default: @@ -4444,6 +4450,16 @@ namespace ts { || token === SyntaxKind.ExclamationToken; } + export function isLogicalOrCoalescingAssignmentOperator(token: SyntaxKind): token is LogicalOrCoalescingAssignmentOperator { + return token === SyntaxKind.BarBarEqualsToken + || token === SyntaxKind.AmpersandAmpersandEqualsToken + || token === SyntaxKind.QuestionQuestionEqualsToken; + } + + export function isLogicalOrCoalescingAssignmentExpression(expr: BinaryExpression): expr is AssignmentExpression> { + return isLogicalOrCoalescingAssignmentOperator(expr.operatorToken.kind); + } + export function isAssignmentOperator(token: SyntaxKind): boolean { return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment; } diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 1d8f86195b8ae..7144a28eebfbf 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -392,6 +392,9 @@ namespace ts { case SyntaxKind.EqualsToken: case SyntaxKind.CommaToken: case SyntaxKind.QuestionQuestionToken: + case SyntaxKind.BarBarEqualsToken: + case SyntaxKind.AmpersandAmpersandEqualsToken: + case SyntaxKind.QuestionQuestionEqualsToken: return true; default: return false; diff --git a/src/testRunner/unittests/factory.ts b/src/testRunner/unittests/factory.ts index ae4258287fedb..b7f510ecdfdc6 100644 --- a/src/testRunner/unittests/factory.ts +++ b/src/testRunner/unittests/factory.ts @@ -77,6 +77,9 @@ namespace ts { checkRhs(SyntaxKind.AmpersandAmpersandToken, /*expectParens*/ true); checkRhs(SyntaxKind.QuestionQuestionToken, /*expectParens*/ true); checkRhs(SyntaxKind.EqualsEqualsToken, /*expectParens*/ true); + checkRhs(SyntaxKind.BarBarEqualsToken, /*expectParens*/ false); + checkRhs(SyntaxKind.AmpersandAmpersandEqualsToken, /*expectParens*/ false); + checkRhs(SyntaxKind.QuestionQuestionEqualsToken, /*expectParens*/ false); }); }); }); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e89d9461ff314..4bec3534e9bae 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -149,281 +149,284 @@ declare namespace ts { GreaterThanGreaterThanGreaterThanEqualsToken = 71, AmpersandEqualsToken = 72, BarEqualsToken = 73, - CaretEqualsToken = 74, - Identifier = 75, - PrivateIdentifier = 76, - BreakKeyword = 77, - CaseKeyword = 78, - CatchKeyword = 79, - ClassKeyword = 80, - ConstKeyword = 81, - ContinueKeyword = 82, - DebuggerKeyword = 83, - DefaultKeyword = 84, - DeleteKeyword = 85, - DoKeyword = 86, - ElseKeyword = 87, - EnumKeyword = 88, - ExportKeyword = 89, - ExtendsKeyword = 90, - FalseKeyword = 91, - FinallyKeyword = 92, - ForKeyword = 93, - FunctionKeyword = 94, - IfKeyword = 95, - ImportKeyword = 96, - InKeyword = 97, - InstanceOfKeyword = 98, - NewKeyword = 99, - NullKeyword = 100, - ReturnKeyword = 101, - SuperKeyword = 102, - SwitchKeyword = 103, - ThisKeyword = 104, - ThrowKeyword = 105, - TrueKeyword = 106, - TryKeyword = 107, - TypeOfKeyword = 108, - VarKeyword = 109, - VoidKeyword = 110, - WhileKeyword = 111, - WithKeyword = 112, - ImplementsKeyword = 113, - InterfaceKeyword = 114, - LetKeyword = 115, - PackageKeyword = 116, - PrivateKeyword = 117, - ProtectedKeyword = 118, - PublicKeyword = 119, - StaticKeyword = 120, - YieldKeyword = 121, - AbstractKeyword = 122, - AsKeyword = 123, - AssertsKeyword = 124, - AnyKeyword = 125, - AsyncKeyword = 126, - AwaitKeyword = 127, - BooleanKeyword = 128, - ConstructorKeyword = 129, - DeclareKeyword = 130, - GetKeyword = 131, - InferKeyword = 132, - IsKeyword = 133, - KeyOfKeyword = 134, - ModuleKeyword = 135, - NamespaceKeyword = 136, - NeverKeyword = 137, - ReadonlyKeyword = 138, - RequireKeyword = 139, - NumberKeyword = 140, - ObjectKeyword = 141, - SetKeyword = 142, - StringKeyword = 143, - SymbolKeyword = 144, - TypeKeyword = 145, - UndefinedKeyword = 146, - UniqueKeyword = 147, - UnknownKeyword = 148, - FromKeyword = 149, - GlobalKeyword = 150, - BigIntKeyword = 151, - OfKeyword = 152, - QualifiedName = 153, - ComputedPropertyName = 154, - TypeParameter = 155, - Parameter = 156, - Decorator = 157, - PropertySignature = 158, - PropertyDeclaration = 159, - MethodSignature = 160, - MethodDeclaration = 161, - Constructor = 162, - GetAccessor = 163, - SetAccessor = 164, - CallSignature = 165, - ConstructSignature = 166, - IndexSignature = 167, - TypePredicate = 168, - TypeReference = 169, - FunctionType = 170, - ConstructorType = 171, - TypeQuery = 172, - TypeLiteral = 173, - ArrayType = 174, - TupleType = 175, - OptionalType = 176, - RestType = 177, - UnionType = 178, - IntersectionType = 179, - ConditionalType = 180, - InferType = 181, - ParenthesizedType = 182, - ThisType = 183, - TypeOperator = 184, - IndexedAccessType = 185, - MappedType = 186, - LiteralType = 187, - NamedTupleMember = 188, - ImportType = 189, - ObjectBindingPattern = 190, - ArrayBindingPattern = 191, - BindingElement = 192, - ArrayLiteralExpression = 193, - ObjectLiteralExpression = 194, - PropertyAccessExpression = 195, - ElementAccessExpression = 196, - CallExpression = 197, - NewExpression = 198, - TaggedTemplateExpression = 199, - TypeAssertionExpression = 200, - ParenthesizedExpression = 201, - FunctionExpression = 202, - ArrowFunction = 203, - DeleteExpression = 204, - TypeOfExpression = 205, - VoidExpression = 206, - AwaitExpression = 207, - PrefixUnaryExpression = 208, - PostfixUnaryExpression = 209, - BinaryExpression = 210, - ConditionalExpression = 211, - TemplateExpression = 212, - YieldExpression = 213, - SpreadElement = 214, - ClassExpression = 215, - OmittedExpression = 216, - ExpressionWithTypeArguments = 217, - AsExpression = 218, - NonNullExpression = 219, - MetaProperty = 220, - SyntheticExpression = 221, - TemplateSpan = 222, - SemicolonClassElement = 223, - Block = 224, - EmptyStatement = 225, - VariableStatement = 226, - ExpressionStatement = 227, - IfStatement = 228, - DoStatement = 229, - WhileStatement = 230, - ForStatement = 231, - ForInStatement = 232, - ForOfStatement = 233, - ContinueStatement = 234, - BreakStatement = 235, - ReturnStatement = 236, - WithStatement = 237, - SwitchStatement = 238, - LabeledStatement = 239, - ThrowStatement = 240, - TryStatement = 241, - DebuggerStatement = 242, - VariableDeclaration = 243, - VariableDeclarationList = 244, - FunctionDeclaration = 245, - ClassDeclaration = 246, - InterfaceDeclaration = 247, - TypeAliasDeclaration = 248, - EnumDeclaration = 249, - ModuleDeclaration = 250, - ModuleBlock = 251, - CaseBlock = 252, - NamespaceExportDeclaration = 253, - ImportEqualsDeclaration = 254, - ImportDeclaration = 255, - ImportClause = 256, - NamespaceImport = 257, - NamedImports = 258, - ImportSpecifier = 259, - ExportAssignment = 260, - ExportDeclaration = 261, - NamedExports = 262, - NamespaceExport = 263, - ExportSpecifier = 264, - MissingDeclaration = 265, - ExternalModuleReference = 266, - JsxElement = 267, - JsxSelfClosingElement = 268, - JsxOpeningElement = 269, - JsxClosingElement = 270, - JsxFragment = 271, - JsxOpeningFragment = 272, - JsxClosingFragment = 273, - JsxAttribute = 274, - JsxAttributes = 275, - JsxSpreadAttribute = 276, - JsxExpression = 277, - CaseClause = 278, - DefaultClause = 279, - HeritageClause = 280, - CatchClause = 281, - PropertyAssignment = 282, - ShorthandPropertyAssignment = 283, - SpreadAssignment = 284, - EnumMember = 285, - UnparsedPrologue = 286, - UnparsedPrepend = 287, - UnparsedText = 288, - UnparsedInternalText = 289, - UnparsedSyntheticReference = 290, - SourceFile = 291, - Bundle = 292, - UnparsedSource = 293, - InputFiles = 294, - JSDocTypeExpression = 295, - JSDocAllType = 296, - JSDocUnknownType = 297, - JSDocNullableType = 298, - JSDocNonNullableType = 299, - JSDocOptionalType = 300, - JSDocFunctionType = 301, - JSDocVariadicType = 302, - JSDocNamepathType = 303, - JSDocComment = 304, - JSDocTypeLiteral = 305, - JSDocSignature = 306, - JSDocTag = 307, - JSDocAugmentsTag = 308, - JSDocImplementsTag = 309, - JSDocAuthorTag = 310, - JSDocClassTag = 311, - JSDocPublicTag = 312, - JSDocPrivateTag = 313, - JSDocProtectedTag = 314, - JSDocReadonlyTag = 315, - JSDocCallbackTag = 316, - JSDocEnumTag = 317, - JSDocParameterTag = 318, - JSDocReturnTag = 319, - JSDocThisTag = 320, - JSDocTypeTag = 321, - JSDocTemplateTag = 322, - JSDocTypedefTag = 323, - JSDocPropertyTag = 324, - SyntaxList = 325, - NotEmittedStatement = 326, - PartiallyEmittedExpression = 327, - CommaListExpression = 328, - MergeDeclarationMarker = 329, - EndOfDeclarationMarker = 330, - SyntheticReferenceExpression = 331, - Count = 332, + BarBarEqualsToken = 74, + AmpersandAmpersandEqualsToken = 75, + QuestionQuestionEqualsToken = 76, + CaretEqualsToken = 77, + Identifier = 78, + PrivateIdentifier = 79, + BreakKeyword = 80, + CaseKeyword = 81, + CatchKeyword = 82, + ClassKeyword = 83, + ConstKeyword = 84, + ContinueKeyword = 85, + DebuggerKeyword = 86, + DefaultKeyword = 87, + DeleteKeyword = 88, + DoKeyword = 89, + ElseKeyword = 90, + EnumKeyword = 91, + ExportKeyword = 92, + ExtendsKeyword = 93, + FalseKeyword = 94, + FinallyKeyword = 95, + ForKeyword = 96, + FunctionKeyword = 97, + IfKeyword = 98, + ImportKeyword = 99, + InKeyword = 100, + InstanceOfKeyword = 101, + NewKeyword = 102, + NullKeyword = 103, + ReturnKeyword = 104, + SuperKeyword = 105, + SwitchKeyword = 106, + ThisKeyword = 107, + ThrowKeyword = 108, + TrueKeyword = 109, + TryKeyword = 110, + TypeOfKeyword = 111, + VarKeyword = 112, + VoidKeyword = 113, + WhileKeyword = 114, + WithKeyword = 115, + ImplementsKeyword = 116, + InterfaceKeyword = 117, + LetKeyword = 118, + PackageKeyword = 119, + PrivateKeyword = 120, + ProtectedKeyword = 121, + PublicKeyword = 122, + StaticKeyword = 123, + YieldKeyword = 124, + AbstractKeyword = 125, + AsKeyword = 126, + AssertsKeyword = 127, + AnyKeyword = 128, + AsyncKeyword = 129, + AwaitKeyword = 130, + BooleanKeyword = 131, + ConstructorKeyword = 132, + DeclareKeyword = 133, + GetKeyword = 134, + InferKeyword = 135, + IsKeyword = 136, + KeyOfKeyword = 137, + ModuleKeyword = 138, + NamespaceKeyword = 139, + NeverKeyword = 140, + ReadonlyKeyword = 141, + RequireKeyword = 142, + NumberKeyword = 143, + ObjectKeyword = 144, + SetKeyword = 145, + StringKeyword = 146, + SymbolKeyword = 147, + TypeKeyword = 148, + UndefinedKeyword = 149, + UniqueKeyword = 150, + UnknownKeyword = 151, + FromKeyword = 152, + GlobalKeyword = 153, + BigIntKeyword = 154, + OfKeyword = 155, + QualifiedName = 156, + ComputedPropertyName = 157, + TypeParameter = 158, + Parameter = 159, + Decorator = 160, + PropertySignature = 161, + PropertyDeclaration = 162, + MethodSignature = 163, + MethodDeclaration = 164, + Constructor = 165, + GetAccessor = 166, + SetAccessor = 167, + CallSignature = 168, + ConstructSignature = 169, + IndexSignature = 170, + TypePredicate = 171, + TypeReference = 172, + FunctionType = 173, + ConstructorType = 174, + TypeQuery = 175, + TypeLiteral = 176, + ArrayType = 177, + TupleType = 178, + OptionalType = 179, + RestType = 180, + UnionType = 181, + IntersectionType = 182, + ConditionalType = 183, + InferType = 184, + ParenthesizedType = 185, + ThisType = 186, + TypeOperator = 187, + IndexedAccessType = 188, + MappedType = 189, + LiteralType = 190, + NamedTupleMember = 191, + ImportType = 192, + ObjectBindingPattern = 193, + ArrayBindingPattern = 194, + BindingElement = 195, + ArrayLiteralExpression = 196, + ObjectLiteralExpression = 197, + PropertyAccessExpression = 198, + ElementAccessExpression = 199, + CallExpression = 200, + NewExpression = 201, + TaggedTemplateExpression = 202, + TypeAssertionExpression = 203, + ParenthesizedExpression = 204, + FunctionExpression = 205, + ArrowFunction = 206, + DeleteExpression = 207, + TypeOfExpression = 208, + VoidExpression = 209, + AwaitExpression = 210, + PrefixUnaryExpression = 211, + PostfixUnaryExpression = 212, + BinaryExpression = 213, + ConditionalExpression = 214, + TemplateExpression = 215, + YieldExpression = 216, + SpreadElement = 217, + ClassExpression = 218, + OmittedExpression = 219, + ExpressionWithTypeArguments = 220, + AsExpression = 221, + NonNullExpression = 222, + MetaProperty = 223, + SyntheticExpression = 224, + TemplateSpan = 225, + SemicolonClassElement = 226, + Block = 227, + EmptyStatement = 228, + VariableStatement = 229, + ExpressionStatement = 230, + IfStatement = 231, + DoStatement = 232, + WhileStatement = 233, + ForStatement = 234, + ForInStatement = 235, + ForOfStatement = 236, + ContinueStatement = 237, + BreakStatement = 238, + ReturnStatement = 239, + WithStatement = 240, + SwitchStatement = 241, + LabeledStatement = 242, + ThrowStatement = 243, + TryStatement = 244, + DebuggerStatement = 245, + VariableDeclaration = 246, + VariableDeclarationList = 247, + FunctionDeclaration = 248, + ClassDeclaration = 249, + InterfaceDeclaration = 250, + TypeAliasDeclaration = 251, + EnumDeclaration = 252, + ModuleDeclaration = 253, + ModuleBlock = 254, + CaseBlock = 255, + NamespaceExportDeclaration = 256, + ImportEqualsDeclaration = 257, + ImportDeclaration = 258, + ImportClause = 259, + NamespaceImport = 260, + NamedImports = 261, + ImportSpecifier = 262, + ExportAssignment = 263, + ExportDeclaration = 264, + NamedExports = 265, + NamespaceExport = 266, + ExportSpecifier = 267, + MissingDeclaration = 268, + ExternalModuleReference = 269, + JsxElement = 270, + JsxSelfClosingElement = 271, + JsxOpeningElement = 272, + JsxClosingElement = 273, + JsxFragment = 274, + JsxOpeningFragment = 275, + JsxClosingFragment = 276, + JsxAttribute = 277, + JsxAttributes = 278, + JsxSpreadAttribute = 279, + JsxExpression = 280, + CaseClause = 281, + DefaultClause = 282, + HeritageClause = 283, + CatchClause = 284, + PropertyAssignment = 285, + ShorthandPropertyAssignment = 286, + SpreadAssignment = 287, + EnumMember = 288, + UnparsedPrologue = 289, + UnparsedPrepend = 290, + UnparsedText = 291, + UnparsedInternalText = 292, + UnparsedSyntheticReference = 293, + SourceFile = 294, + Bundle = 295, + UnparsedSource = 296, + InputFiles = 297, + JSDocTypeExpression = 298, + JSDocAllType = 299, + JSDocUnknownType = 300, + JSDocNullableType = 301, + JSDocNonNullableType = 302, + JSDocOptionalType = 303, + JSDocFunctionType = 304, + JSDocVariadicType = 305, + JSDocNamepathType = 306, + JSDocComment = 307, + JSDocTypeLiteral = 308, + JSDocSignature = 309, + JSDocTag = 310, + JSDocAugmentsTag = 311, + JSDocImplementsTag = 312, + JSDocAuthorTag = 313, + JSDocClassTag = 314, + JSDocPublicTag = 315, + JSDocPrivateTag = 316, + JSDocProtectedTag = 317, + JSDocReadonlyTag = 318, + JSDocCallbackTag = 319, + JSDocEnumTag = 320, + JSDocParameterTag = 321, + JSDocReturnTag = 322, + JSDocThisTag = 323, + JSDocTypeTag = 324, + JSDocTemplateTag = 325, + JSDocTypedefTag = 326, + JSDocPropertyTag = 327, + SyntaxList = 328, + NotEmittedStatement = 329, + PartiallyEmittedExpression = 330, + CommaListExpression = 331, + MergeDeclarationMarker = 332, + EndOfDeclarationMarker = 333, + SyntheticReferenceExpression = 334, + Count = 335, FirstAssignment = 62, - LastAssignment = 74, + LastAssignment = 77, FirstCompoundAssignment = 63, - LastCompoundAssignment = 74, - FirstReservedWord = 77, - LastReservedWord = 112, - FirstKeyword = 77, - LastKeyword = 152, - FirstFutureReservedWord = 113, - LastFutureReservedWord = 121, - FirstTypeNode = 168, - LastTypeNode = 189, + LastCompoundAssignment = 77, + FirstReservedWord = 80, + LastReservedWord = 115, + FirstKeyword = 80, + LastKeyword = 155, + FirstFutureReservedWord = 116, + LastFutureReservedWord = 124, + FirstTypeNode = 171, + LastTypeNode = 192, FirstPunctuation = 18, - LastPunctuation = 74, + LastPunctuation = 77, FirstToken = 0, - LastToken = 152, + LastToken = 155, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -431,14 +434,14 @@ declare namespace ts { FirstTemplateToken = 14, LastTemplateToken = 17, FirstBinaryOperator = 29, - LastBinaryOperator = 74, - FirstStatement = 226, - LastStatement = 242, - FirstNode = 153, - FirstJSDocNode = 295, - LastJSDocNode = 324, - FirstJSDocTagNode = 307, - LastJSDocTagNode = 324, + LastBinaryOperator = 77, + FirstStatement = 229, + LastStatement = 245, + FirstNode = 156, + FirstJSDocNode = 298, + LastJSDocNode = 327, + FirstJSDocTagNode = 310, + LastJSDocTagNode = 327, } export enum NodeFlags { None = 0, @@ -972,10 +975,11 @@ declare namespace ts { export type BitwiseOperatorOrHigher = EqualityOperatorOrHigher | BitwiseOperator; export type LogicalOperator = SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken; export type LogicalOperatorOrHigher = BitwiseOperatorOrHigher | LogicalOperator; - export type CompoundAssignmentOperator = SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken; + export type CompoundAssignmentOperator = SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken; export type AssignmentOperator = SyntaxKind.EqualsToken | CompoundAssignmentOperator; export type AssignmentOperatorOrHigher = SyntaxKind.QuestionQuestionToken | LogicalOperatorOrHigher | AssignmentOperator; export type BinaryOperator = AssignmentOperatorOrHigher | SyntaxKind.CommaToken; + export type LogicalOrCoalescingAssignmentOperator = SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.QuestionQuestionEqualsToken; export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { kind: SyntaxKind.BinaryExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2213fd4be6a66..f163a5f4ee395 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -149,281 +149,284 @@ declare namespace ts { GreaterThanGreaterThanGreaterThanEqualsToken = 71, AmpersandEqualsToken = 72, BarEqualsToken = 73, - CaretEqualsToken = 74, - Identifier = 75, - PrivateIdentifier = 76, - BreakKeyword = 77, - CaseKeyword = 78, - CatchKeyword = 79, - ClassKeyword = 80, - ConstKeyword = 81, - ContinueKeyword = 82, - DebuggerKeyword = 83, - DefaultKeyword = 84, - DeleteKeyword = 85, - DoKeyword = 86, - ElseKeyword = 87, - EnumKeyword = 88, - ExportKeyword = 89, - ExtendsKeyword = 90, - FalseKeyword = 91, - FinallyKeyword = 92, - ForKeyword = 93, - FunctionKeyword = 94, - IfKeyword = 95, - ImportKeyword = 96, - InKeyword = 97, - InstanceOfKeyword = 98, - NewKeyword = 99, - NullKeyword = 100, - ReturnKeyword = 101, - SuperKeyword = 102, - SwitchKeyword = 103, - ThisKeyword = 104, - ThrowKeyword = 105, - TrueKeyword = 106, - TryKeyword = 107, - TypeOfKeyword = 108, - VarKeyword = 109, - VoidKeyword = 110, - WhileKeyword = 111, - WithKeyword = 112, - ImplementsKeyword = 113, - InterfaceKeyword = 114, - LetKeyword = 115, - PackageKeyword = 116, - PrivateKeyword = 117, - ProtectedKeyword = 118, - PublicKeyword = 119, - StaticKeyword = 120, - YieldKeyword = 121, - AbstractKeyword = 122, - AsKeyword = 123, - AssertsKeyword = 124, - AnyKeyword = 125, - AsyncKeyword = 126, - AwaitKeyword = 127, - BooleanKeyword = 128, - ConstructorKeyword = 129, - DeclareKeyword = 130, - GetKeyword = 131, - InferKeyword = 132, - IsKeyword = 133, - KeyOfKeyword = 134, - ModuleKeyword = 135, - NamespaceKeyword = 136, - NeverKeyword = 137, - ReadonlyKeyword = 138, - RequireKeyword = 139, - NumberKeyword = 140, - ObjectKeyword = 141, - SetKeyword = 142, - StringKeyword = 143, - SymbolKeyword = 144, - TypeKeyword = 145, - UndefinedKeyword = 146, - UniqueKeyword = 147, - UnknownKeyword = 148, - FromKeyword = 149, - GlobalKeyword = 150, - BigIntKeyword = 151, - OfKeyword = 152, - QualifiedName = 153, - ComputedPropertyName = 154, - TypeParameter = 155, - Parameter = 156, - Decorator = 157, - PropertySignature = 158, - PropertyDeclaration = 159, - MethodSignature = 160, - MethodDeclaration = 161, - Constructor = 162, - GetAccessor = 163, - SetAccessor = 164, - CallSignature = 165, - ConstructSignature = 166, - IndexSignature = 167, - TypePredicate = 168, - TypeReference = 169, - FunctionType = 170, - ConstructorType = 171, - TypeQuery = 172, - TypeLiteral = 173, - ArrayType = 174, - TupleType = 175, - OptionalType = 176, - RestType = 177, - UnionType = 178, - IntersectionType = 179, - ConditionalType = 180, - InferType = 181, - ParenthesizedType = 182, - ThisType = 183, - TypeOperator = 184, - IndexedAccessType = 185, - MappedType = 186, - LiteralType = 187, - NamedTupleMember = 188, - ImportType = 189, - ObjectBindingPattern = 190, - ArrayBindingPattern = 191, - BindingElement = 192, - ArrayLiteralExpression = 193, - ObjectLiteralExpression = 194, - PropertyAccessExpression = 195, - ElementAccessExpression = 196, - CallExpression = 197, - NewExpression = 198, - TaggedTemplateExpression = 199, - TypeAssertionExpression = 200, - ParenthesizedExpression = 201, - FunctionExpression = 202, - ArrowFunction = 203, - DeleteExpression = 204, - TypeOfExpression = 205, - VoidExpression = 206, - AwaitExpression = 207, - PrefixUnaryExpression = 208, - PostfixUnaryExpression = 209, - BinaryExpression = 210, - ConditionalExpression = 211, - TemplateExpression = 212, - YieldExpression = 213, - SpreadElement = 214, - ClassExpression = 215, - OmittedExpression = 216, - ExpressionWithTypeArguments = 217, - AsExpression = 218, - NonNullExpression = 219, - MetaProperty = 220, - SyntheticExpression = 221, - TemplateSpan = 222, - SemicolonClassElement = 223, - Block = 224, - EmptyStatement = 225, - VariableStatement = 226, - ExpressionStatement = 227, - IfStatement = 228, - DoStatement = 229, - WhileStatement = 230, - ForStatement = 231, - ForInStatement = 232, - ForOfStatement = 233, - ContinueStatement = 234, - BreakStatement = 235, - ReturnStatement = 236, - WithStatement = 237, - SwitchStatement = 238, - LabeledStatement = 239, - ThrowStatement = 240, - TryStatement = 241, - DebuggerStatement = 242, - VariableDeclaration = 243, - VariableDeclarationList = 244, - FunctionDeclaration = 245, - ClassDeclaration = 246, - InterfaceDeclaration = 247, - TypeAliasDeclaration = 248, - EnumDeclaration = 249, - ModuleDeclaration = 250, - ModuleBlock = 251, - CaseBlock = 252, - NamespaceExportDeclaration = 253, - ImportEqualsDeclaration = 254, - ImportDeclaration = 255, - ImportClause = 256, - NamespaceImport = 257, - NamedImports = 258, - ImportSpecifier = 259, - ExportAssignment = 260, - ExportDeclaration = 261, - NamedExports = 262, - NamespaceExport = 263, - ExportSpecifier = 264, - MissingDeclaration = 265, - ExternalModuleReference = 266, - JsxElement = 267, - JsxSelfClosingElement = 268, - JsxOpeningElement = 269, - JsxClosingElement = 270, - JsxFragment = 271, - JsxOpeningFragment = 272, - JsxClosingFragment = 273, - JsxAttribute = 274, - JsxAttributes = 275, - JsxSpreadAttribute = 276, - JsxExpression = 277, - CaseClause = 278, - DefaultClause = 279, - HeritageClause = 280, - CatchClause = 281, - PropertyAssignment = 282, - ShorthandPropertyAssignment = 283, - SpreadAssignment = 284, - EnumMember = 285, - UnparsedPrologue = 286, - UnparsedPrepend = 287, - UnparsedText = 288, - UnparsedInternalText = 289, - UnparsedSyntheticReference = 290, - SourceFile = 291, - Bundle = 292, - UnparsedSource = 293, - InputFiles = 294, - JSDocTypeExpression = 295, - JSDocAllType = 296, - JSDocUnknownType = 297, - JSDocNullableType = 298, - JSDocNonNullableType = 299, - JSDocOptionalType = 300, - JSDocFunctionType = 301, - JSDocVariadicType = 302, - JSDocNamepathType = 303, - JSDocComment = 304, - JSDocTypeLiteral = 305, - JSDocSignature = 306, - JSDocTag = 307, - JSDocAugmentsTag = 308, - JSDocImplementsTag = 309, - JSDocAuthorTag = 310, - JSDocClassTag = 311, - JSDocPublicTag = 312, - JSDocPrivateTag = 313, - JSDocProtectedTag = 314, - JSDocReadonlyTag = 315, - JSDocCallbackTag = 316, - JSDocEnumTag = 317, - JSDocParameterTag = 318, - JSDocReturnTag = 319, - JSDocThisTag = 320, - JSDocTypeTag = 321, - JSDocTemplateTag = 322, - JSDocTypedefTag = 323, - JSDocPropertyTag = 324, - SyntaxList = 325, - NotEmittedStatement = 326, - PartiallyEmittedExpression = 327, - CommaListExpression = 328, - MergeDeclarationMarker = 329, - EndOfDeclarationMarker = 330, - SyntheticReferenceExpression = 331, - Count = 332, + BarBarEqualsToken = 74, + AmpersandAmpersandEqualsToken = 75, + QuestionQuestionEqualsToken = 76, + CaretEqualsToken = 77, + Identifier = 78, + PrivateIdentifier = 79, + BreakKeyword = 80, + CaseKeyword = 81, + CatchKeyword = 82, + ClassKeyword = 83, + ConstKeyword = 84, + ContinueKeyword = 85, + DebuggerKeyword = 86, + DefaultKeyword = 87, + DeleteKeyword = 88, + DoKeyword = 89, + ElseKeyword = 90, + EnumKeyword = 91, + ExportKeyword = 92, + ExtendsKeyword = 93, + FalseKeyword = 94, + FinallyKeyword = 95, + ForKeyword = 96, + FunctionKeyword = 97, + IfKeyword = 98, + ImportKeyword = 99, + InKeyword = 100, + InstanceOfKeyword = 101, + NewKeyword = 102, + NullKeyword = 103, + ReturnKeyword = 104, + SuperKeyword = 105, + SwitchKeyword = 106, + ThisKeyword = 107, + ThrowKeyword = 108, + TrueKeyword = 109, + TryKeyword = 110, + TypeOfKeyword = 111, + VarKeyword = 112, + VoidKeyword = 113, + WhileKeyword = 114, + WithKeyword = 115, + ImplementsKeyword = 116, + InterfaceKeyword = 117, + LetKeyword = 118, + PackageKeyword = 119, + PrivateKeyword = 120, + ProtectedKeyword = 121, + PublicKeyword = 122, + StaticKeyword = 123, + YieldKeyword = 124, + AbstractKeyword = 125, + AsKeyword = 126, + AssertsKeyword = 127, + AnyKeyword = 128, + AsyncKeyword = 129, + AwaitKeyword = 130, + BooleanKeyword = 131, + ConstructorKeyword = 132, + DeclareKeyword = 133, + GetKeyword = 134, + InferKeyword = 135, + IsKeyword = 136, + KeyOfKeyword = 137, + ModuleKeyword = 138, + NamespaceKeyword = 139, + NeverKeyword = 140, + ReadonlyKeyword = 141, + RequireKeyword = 142, + NumberKeyword = 143, + ObjectKeyword = 144, + SetKeyword = 145, + StringKeyword = 146, + SymbolKeyword = 147, + TypeKeyword = 148, + UndefinedKeyword = 149, + UniqueKeyword = 150, + UnknownKeyword = 151, + FromKeyword = 152, + GlobalKeyword = 153, + BigIntKeyword = 154, + OfKeyword = 155, + QualifiedName = 156, + ComputedPropertyName = 157, + TypeParameter = 158, + Parameter = 159, + Decorator = 160, + PropertySignature = 161, + PropertyDeclaration = 162, + MethodSignature = 163, + MethodDeclaration = 164, + Constructor = 165, + GetAccessor = 166, + SetAccessor = 167, + CallSignature = 168, + ConstructSignature = 169, + IndexSignature = 170, + TypePredicate = 171, + TypeReference = 172, + FunctionType = 173, + ConstructorType = 174, + TypeQuery = 175, + TypeLiteral = 176, + ArrayType = 177, + TupleType = 178, + OptionalType = 179, + RestType = 180, + UnionType = 181, + IntersectionType = 182, + ConditionalType = 183, + InferType = 184, + ParenthesizedType = 185, + ThisType = 186, + TypeOperator = 187, + IndexedAccessType = 188, + MappedType = 189, + LiteralType = 190, + NamedTupleMember = 191, + ImportType = 192, + ObjectBindingPattern = 193, + ArrayBindingPattern = 194, + BindingElement = 195, + ArrayLiteralExpression = 196, + ObjectLiteralExpression = 197, + PropertyAccessExpression = 198, + ElementAccessExpression = 199, + CallExpression = 200, + NewExpression = 201, + TaggedTemplateExpression = 202, + TypeAssertionExpression = 203, + ParenthesizedExpression = 204, + FunctionExpression = 205, + ArrowFunction = 206, + DeleteExpression = 207, + TypeOfExpression = 208, + VoidExpression = 209, + AwaitExpression = 210, + PrefixUnaryExpression = 211, + PostfixUnaryExpression = 212, + BinaryExpression = 213, + ConditionalExpression = 214, + TemplateExpression = 215, + YieldExpression = 216, + SpreadElement = 217, + ClassExpression = 218, + OmittedExpression = 219, + ExpressionWithTypeArguments = 220, + AsExpression = 221, + NonNullExpression = 222, + MetaProperty = 223, + SyntheticExpression = 224, + TemplateSpan = 225, + SemicolonClassElement = 226, + Block = 227, + EmptyStatement = 228, + VariableStatement = 229, + ExpressionStatement = 230, + IfStatement = 231, + DoStatement = 232, + WhileStatement = 233, + ForStatement = 234, + ForInStatement = 235, + ForOfStatement = 236, + ContinueStatement = 237, + BreakStatement = 238, + ReturnStatement = 239, + WithStatement = 240, + SwitchStatement = 241, + LabeledStatement = 242, + ThrowStatement = 243, + TryStatement = 244, + DebuggerStatement = 245, + VariableDeclaration = 246, + VariableDeclarationList = 247, + FunctionDeclaration = 248, + ClassDeclaration = 249, + InterfaceDeclaration = 250, + TypeAliasDeclaration = 251, + EnumDeclaration = 252, + ModuleDeclaration = 253, + ModuleBlock = 254, + CaseBlock = 255, + NamespaceExportDeclaration = 256, + ImportEqualsDeclaration = 257, + ImportDeclaration = 258, + ImportClause = 259, + NamespaceImport = 260, + NamedImports = 261, + ImportSpecifier = 262, + ExportAssignment = 263, + ExportDeclaration = 264, + NamedExports = 265, + NamespaceExport = 266, + ExportSpecifier = 267, + MissingDeclaration = 268, + ExternalModuleReference = 269, + JsxElement = 270, + JsxSelfClosingElement = 271, + JsxOpeningElement = 272, + JsxClosingElement = 273, + JsxFragment = 274, + JsxOpeningFragment = 275, + JsxClosingFragment = 276, + JsxAttribute = 277, + JsxAttributes = 278, + JsxSpreadAttribute = 279, + JsxExpression = 280, + CaseClause = 281, + DefaultClause = 282, + HeritageClause = 283, + CatchClause = 284, + PropertyAssignment = 285, + ShorthandPropertyAssignment = 286, + SpreadAssignment = 287, + EnumMember = 288, + UnparsedPrologue = 289, + UnparsedPrepend = 290, + UnparsedText = 291, + UnparsedInternalText = 292, + UnparsedSyntheticReference = 293, + SourceFile = 294, + Bundle = 295, + UnparsedSource = 296, + InputFiles = 297, + JSDocTypeExpression = 298, + JSDocAllType = 299, + JSDocUnknownType = 300, + JSDocNullableType = 301, + JSDocNonNullableType = 302, + JSDocOptionalType = 303, + JSDocFunctionType = 304, + JSDocVariadicType = 305, + JSDocNamepathType = 306, + JSDocComment = 307, + JSDocTypeLiteral = 308, + JSDocSignature = 309, + JSDocTag = 310, + JSDocAugmentsTag = 311, + JSDocImplementsTag = 312, + JSDocAuthorTag = 313, + JSDocClassTag = 314, + JSDocPublicTag = 315, + JSDocPrivateTag = 316, + JSDocProtectedTag = 317, + JSDocReadonlyTag = 318, + JSDocCallbackTag = 319, + JSDocEnumTag = 320, + JSDocParameterTag = 321, + JSDocReturnTag = 322, + JSDocThisTag = 323, + JSDocTypeTag = 324, + JSDocTemplateTag = 325, + JSDocTypedefTag = 326, + JSDocPropertyTag = 327, + SyntaxList = 328, + NotEmittedStatement = 329, + PartiallyEmittedExpression = 330, + CommaListExpression = 331, + MergeDeclarationMarker = 332, + EndOfDeclarationMarker = 333, + SyntheticReferenceExpression = 334, + Count = 335, FirstAssignment = 62, - LastAssignment = 74, + LastAssignment = 77, FirstCompoundAssignment = 63, - LastCompoundAssignment = 74, - FirstReservedWord = 77, - LastReservedWord = 112, - FirstKeyword = 77, - LastKeyword = 152, - FirstFutureReservedWord = 113, - LastFutureReservedWord = 121, - FirstTypeNode = 168, - LastTypeNode = 189, + LastCompoundAssignment = 77, + FirstReservedWord = 80, + LastReservedWord = 115, + FirstKeyword = 80, + LastKeyword = 155, + FirstFutureReservedWord = 116, + LastFutureReservedWord = 124, + FirstTypeNode = 171, + LastTypeNode = 192, FirstPunctuation = 18, - LastPunctuation = 74, + LastPunctuation = 77, FirstToken = 0, - LastToken = 152, + LastToken = 155, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -431,14 +434,14 @@ declare namespace ts { FirstTemplateToken = 14, LastTemplateToken = 17, FirstBinaryOperator = 29, - LastBinaryOperator = 74, - FirstStatement = 226, - LastStatement = 242, - FirstNode = 153, - FirstJSDocNode = 295, - LastJSDocNode = 324, - FirstJSDocTagNode = 307, - LastJSDocTagNode = 324, + LastBinaryOperator = 77, + FirstStatement = 229, + LastStatement = 245, + FirstNode = 156, + FirstJSDocNode = 298, + LastJSDocNode = 327, + FirstJSDocTagNode = 310, + LastJSDocTagNode = 327, } export enum NodeFlags { None = 0, @@ -972,10 +975,11 @@ declare namespace ts { export type BitwiseOperatorOrHigher = EqualityOperatorOrHigher | BitwiseOperator; export type LogicalOperator = SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken; export type LogicalOperatorOrHigher = BitwiseOperatorOrHigher | LogicalOperator; - export type CompoundAssignmentOperator = SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken; + export type CompoundAssignmentOperator = SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken; export type AssignmentOperator = SyntaxKind.EqualsToken | CompoundAssignmentOperator; export type AssignmentOperatorOrHigher = SyntaxKind.QuestionQuestionToken | LogicalOperatorOrHigher | AssignmentOperator; export type BinaryOperator = AssignmentOperatorOrHigher | SyntaxKind.CommaToken; + export type LogicalOrCoalescingAssignmentOperator = SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.QuestionQuestionEqualsToken; export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { kind: SyntaxKind.BinaryExpression; diff --git a/tests/baselines/reference/logicalAssignment1(target=es2015).js b/tests/baselines/reference/logicalAssignment1(target=es2015).js new file mode 100644 index 0000000000000..db6e540789a5e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=es2015).js @@ -0,0 +1,39 @@ +//// [logicalAssignment1.ts] +declare let a: string | undefined +declare let b: string | undefined +declare let c: string | undefined + +declare let d: number | undefined +declare let e: number | undefined +declare let f: number | undefined + +declare let g: 0 | 1 | 42 +declare let h: 0 | 1 | 42 +declare let i: 0 | 1 | 42 + + +a &&= "foo" +b ||= "foo" +c ??= "foo" + + +d &&= 42 +e ||= 42 +f ??= 42 + +g &&= 42 +h ||= 42 +i ??= 42 + + +//// [logicalAssignment1.js] +"use strict"; +a && (a = "foo"); +b || (b = "foo"); +c !== null && c !== void 0 ? c : (c = "foo"); +d && (d = 42); +e || (e = 42); +f !== null && f !== void 0 ? f : (f = 42); +g && (g = 42); +h || (h = 42); +i !== null && i !== void 0 ? i : (i = 42); diff --git a/tests/baselines/reference/logicalAssignment1(target=es2015).symbols b/tests/baselines/reference/logicalAssignment1(target=es2015).symbols new file mode 100644 index 0000000000000..5705fc2d1042a --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=es2015).symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts === +declare let a: string | undefined +>a : Symbol(a, Decl(logicalAssignment1.ts, 0, 11)) + +declare let b: string | undefined +>b : Symbol(b, Decl(logicalAssignment1.ts, 1, 11)) + +declare let c: string | undefined +>c : Symbol(c, Decl(logicalAssignment1.ts, 2, 11)) + +declare let d: number | undefined +>d : Symbol(d, Decl(logicalAssignment1.ts, 4, 11)) + +declare let e: number | undefined +>e : Symbol(e, Decl(logicalAssignment1.ts, 5, 11)) + +declare let f: number | undefined +>f : Symbol(f, Decl(logicalAssignment1.ts, 6, 11)) + +declare let g: 0 | 1 | 42 +>g : Symbol(g, Decl(logicalAssignment1.ts, 8, 11)) + +declare let h: 0 | 1 | 42 +>h : Symbol(h, Decl(logicalAssignment1.ts, 9, 11)) + +declare let i: 0 | 1 | 42 +>i : Symbol(i, Decl(logicalAssignment1.ts, 10, 11)) + + +a &&= "foo" +>a : Symbol(a, Decl(logicalAssignment1.ts, 0, 11)) + +b ||= "foo" +>b : Symbol(b, Decl(logicalAssignment1.ts, 1, 11)) + +c ??= "foo" +>c : Symbol(c, Decl(logicalAssignment1.ts, 2, 11)) + + +d &&= 42 +>d : Symbol(d, Decl(logicalAssignment1.ts, 4, 11)) + +e ||= 42 +>e : Symbol(e, Decl(logicalAssignment1.ts, 5, 11)) + +f ??= 42 +>f : Symbol(f, Decl(logicalAssignment1.ts, 6, 11)) + +g &&= 42 +>g : Symbol(g, Decl(logicalAssignment1.ts, 8, 11)) + +h ||= 42 +>h : Symbol(h, Decl(logicalAssignment1.ts, 9, 11)) + +i ??= 42 +>i : Symbol(i, Decl(logicalAssignment1.ts, 10, 11)) + diff --git a/tests/baselines/reference/logicalAssignment1(target=es2015).types b/tests/baselines/reference/logicalAssignment1(target=es2015).types new file mode 100644 index 0000000000000..29a224ecef79b --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=es2015).types @@ -0,0 +1,75 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts === +declare let a: string | undefined +>a : string | undefined + +declare let b: string | undefined +>b : string | undefined + +declare let c: string | undefined +>c : string | undefined + +declare let d: number | undefined +>d : number | undefined + +declare let e: number | undefined +>e : number | undefined + +declare let f: number | undefined +>f : number | undefined + +declare let g: 0 | 1 | 42 +>g : 0 | 1 | 42 + +declare let h: 0 | 1 | 42 +>h : 0 | 1 | 42 + +declare let i: 0 | 1 | 42 +>i : 0 | 1 | 42 + + +a &&= "foo" +>a &&= "foo" : "" | "foo" | undefined +>a : string | undefined +>"foo" : "foo" + +b ||= "foo" +>b ||= "foo" : string +>b : string | undefined +>"foo" : "foo" + +c ??= "foo" +>c ??= "foo" : string +>c : string | undefined +>"foo" : "foo" + + +d &&= 42 +>d &&= 42 : 0 | 42 | undefined +>d : number | undefined +>42 : 42 + +e ||= 42 +>e ||= 42 : number +>e : number | undefined +>42 : 42 + +f ??= 42 +>f ??= 42 : number +>f : number | undefined +>42 : 42 + +g &&= 42 +>g &&= 42 : 0 | 42 +>g : 0 | 1 | 42 +>42 : 42 + +h ||= 42 +>h ||= 42 : 1 | 42 +>h : 0 | 1 | 42 +>42 : 42 + +i ??= 42 +>i ??= 42 : 0 | 1 | 42 +>i : 0 | 1 | 42 +>42 : 42 + diff --git a/tests/baselines/reference/logicalAssignment1(target=es2020).js b/tests/baselines/reference/logicalAssignment1(target=es2020).js new file mode 100644 index 0000000000000..dd527ab2139d8 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=es2020).js @@ -0,0 +1,39 @@ +//// [logicalAssignment1.ts] +declare let a: string | undefined +declare let b: string | undefined +declare let c: string | undefined + +declare let d: number | undefined +declare let e: number | undefined +declare let f: number | undefined + +declare let g: 0 | 1 | 42 +declare let h: 0 | 1 | 42 +declare let i: 0 | 1 | 42 + + +a &&= "foo" +b ||= "foo" +c ??= "foo" + + +d &&= 42 +e ||= 42 +f ??= 42 + +g &&= 42 +h ||= 42 +i ??= 42 + + +//// [logicalAssignment1.js] +"use strict"; +a && (a = "foo"); +b || (b = "foo"); +c ?? (c = "foo"); +d && (d = 42); +e || (e = 42); +f ?? (f = 42); +g && (g = 42); +h || (h = 42); +i ?? (i = 42); diff --git a/tests/baselines/reference/logicalAssignment1(target=es2020).symbols b/tests/baselines/reference/logicalAssignment1(target=es2020).symbols new file mode 100644 index 0000000000000..5705fc2d1042a --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=es2020).symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts === +declare let a: string | undefined +>a : Symbol(a, Decl(logicalAssignment1.ts, 0, 11)) + +declare let b: string | undefined +>b : Symbol(b, Decl(logicalAssignment1.ts, 1, 11)) + +declare let c: string | undefined +>c : Symbol(c, Decl(logicalAssignment1.ts, 2, 11)) + +declare let d: number | undefined +>d : Symbol(d, Decl(logicalAssignment1.ts, 4, 11)) + +declare let e: number | undefined +>e : Symbol(e, Decl(logicalAssignment1.ts, 5, 11)) + +declare let f: number | undefined +>f : Symbol(f, Decl(logicalAssignment1.ts, 6, 11)) + +declare let g: 0 | 1 | 42 +>g : Symbol(g, Decl(logicalAssignment1.ts, 8, 11)) + +declare let h: 0 | 1 | 42 +>h : Symbol(h, Decl(logicalAssignment1.ts, 9, 11)) + +declare let i: 0 | 1 | 42 +>i : Symbol(i, Decl(logicalAssignment1.ts, 10, 11)) + + +a &&= "foo" +>a : Symbol(a, Decl(logicalAssignment1.ts, 0, 11)) + +b ||= "foo" +>b : Symbol(b, Decl(logicalAssignment1.ts, 1, 11)) + +c ??= "foo" +>c : Symbol(c, Decl(logicalAssignment1.ts, 2, 11)) + + +d &&= 42 +>d : Symbol(d, Decl(logicalAssignment1.ts, 4, 11)) + +e ||= 42 +>e : Symbol(e, Decl(logicalAssignment1.ts, 5, 11)) + +f ??= 42 +>f : Symbol(f, Decl(logicalAssignment1.ts, 6, 11)) + +g &&= 42 +>g : Symbol(g, Decl(logicalAssignment1.ts, 8, 11)) + +h ||= 42 +>h : Symbol(h, Decl(logicalAssignment1.ts, 9, 11)) + +i ??= 42 +>i : Symbol(i, Decl(logicalAssignment1.ts, 10, 11)) + diff --git a/tests/baselines/reference/logicalAssignment1(target=es2020).types b/tests/baselines/reference/logicalAssignment1(target=es2020).types new file mode 100644 index 0000000000000..29a224ecef79b --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=es2020).types @@ -0,0 +1,75 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts === +declare let a: string | undefined +>a : string | undefined + +declare let b: string | undefined +>b : string | undefined + +declare let c: string | undefined +>c : string | undefined + +declare let d: number | undefined +>d : number | undefined + +declare let e: number | undefined +>e : number | undefined + +declare let f: number | undefined +>f : number | undefined + +declare let g: 0 | 1 | 42 +>g : 0 | 1 | 42 + +declare let h: 0 | 1 | 42 +>h : 0 | 1 | 42 + +declare let i: 0 | 1 | 42 +>i : 0 | 1 | 42 + + +a &&= "foo" +>a &&= "foo" : "" | "foo" | undefined +>a : string | undefined +>"foo" : "foo" + +b ||= "foo" +>b ||= "foo" : string +>b : string | undefined +>"foo" : "foo" + +c ??= "foo" +>c ??= "foo" : string +>c : string | undefined +>"foo" : "foo" + + +d &&= 42 +>d &&= 42 : 0 | 42 | undefined +>d : number | undefined +>42 : 42 + +e ||= 42 +>e ||= 42 : number +>e : number | undefined +>42 : 42 + +f ??= 42 +>f ??= 42 : number +>f : number | undefined +>42 : 42 + +g &&= 42 +>g &&= 42 : 0 | 42 +>g : 0 | 1 | 42 +>42 : 42 + +h ||= 42 +>h ||= 42 : 1 | 42 +>h : 0 | 1 | 42 +>42 : 42 + +i ??= 42 +>i ??= 42 : 0 | 1 | 42 +>i : 0 | 1 | 42 +>42 : 42 + diff --git a/tests/baselines/reference/logicalAssignment1(target=esnext).js b/tests/baselines/reference/logicalAssignment1(target=esnext).js new file mode 100644 index 0000000000000..4adf005014e39 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=esnext).js @@ -0,0 +1,39 @@ +//// [logicalAssignment1.ts] +declare let a: string | undefined +declare let b: string | undefined +declare let c: string | undefined + +declare let d: number | undefined +declare let e: number | undefined +declare let f: number | undefined + +declare let g: 0 | 1 | 42 +declare let h: 0 | 1 | 42 +declare let i: 0 | 1 | 42 + + +a &&= "foo" +b ||= "foo" +c ??= "foo" + + +d &&= 42 +e ||= 42 +f ??= 42 + +g &&= 42 +h ||= 42 +i ??= 42 + + +//// [logicalAssignment1.js] +"use strict"; +a &&= "foo"; +b ||= "foo"; +c ??= "foo"; +d &&= 42; +e ||= 42; +f ??= 42; +g &&= 42; +h ||= 42; +i ??= 42; diff --git a/tests/baselines/reference/logicalAssignment1(target=esnext).symbols b/tests/baselines/reference/logicalAssignment1(target=esnext).symbols new file mode 100644 index 0000000000000..5705fc2d1042a --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=esnext).symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts === +declare let a: string | undefined +>a : Symbol(a, Decl(logicalAssignment1.ts, 0, 11)) + +declare let b: string | undefined +>b : Symbol(b, Decl(logicalAssignment1.ts, 1, 11)) + +declare let c: string | undefined +>c : Symbol(c, Decl(logicalAssignment1.ts, 2, 11)) + +declare let d: number | undefined +>d : Symbol(d, Decl(logicalAssignment1.ts, 4, 11)) + +declare let e: number | undefined +>e : Symbol(e, Decl(logicalAssignment1.ts, 5, 11)) + +declare let f: number | undefined +>f : Symbol(f, Decl(logicalAssignment1.ts, 6, 11)) + +declare let g: 0 | 1 | 42 +>g : Symbol(g, Decl(logicalAssignment1.ts, 8, 11)) + +declare let h: 0 | 1 | 42 +>h : Symbol(h, Decl(logicalAssignment1.ts, 9, 11)) + +declare let i: 0 | 1 | 42 +>i : Symbol(i, Decl(logicalAssignment1.ts, 10, 11)) + + +a &&= "foo" +>a : Symbol(a, Decl(logicalAssignment1.ts, 0, 11)) + +b ||= "foo" +>b : Symbol(b, Decl(logicalAssignment1.ts, 1, 11)) + +c ??= "foo" +>c : Symbol(c, Decl(logicalAssignment1.ts, 2, 11)) + + +d &&= 42 +>d : Symbol(d, Decl(logicalAssignment1.ts, 4, 11)) + +e ||= 42 +>e : Symbol(e, Decl(logicalAssignment1.ts, 5, 11)) + +f ??= 42 +>f : Symbol(f, Decl(logicalAssignment1.ts, 6, 11)) + +g &&= 42 +>g : Symbol(g, Decl(logicalAssignment1.ts, 8, 11)) + +h ||= 42 +>h : Symbol(h, Decl(logicalAssignment1.ts, 9, 11)) + +i ??= 42 +>i : Symbol(i, Decl(logicalAssignment1.ts, 10, 11)) + diff --git a/tests/baselines/reference/logicalAssignment1(target=esnext).types b/tests/baselines/reference/logicalAssignment1(target=esnext).types new file mode 100644 index 0000000000000..29a224ecef79b --- /dev/null +++ b/tests/baselines/reference/logicalAssignment1(target=esnext).types @@ -0,0 +1,75 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts === +declare let a: string | undefined +>a : string | undefined + +declare let b: string | undefined +>b : string | undefined + +declare let c: string | undefined +>c : string | undefined + +declare let d: number | undefined +>d : number | undefined + +declare let e: number | undefined +>e : number | undefined + +declare let f: number | undefined +>f : number | undefined + +declare let g: 0 | 1 | 42 +>g : 0 | 1 | 42 + +declare let h: 0 | 1 | 42 +>h : 0 | 1 | 42 + +declare let i: 0 | 1 | 42 +>i : 0 | 1 | 42 + + +a &&= "foo" +>a &&= "foo" : "" | "foo" | undefined +>a : string | undefined +>"foo" : "foo" + +b ||= "foo" +>b ||= "foo" : string +>b : string | undefined +>"foo" : "foo" + +c ??= "foo" +>c ??= "foo" : string +>c : string | undefined +>"foo" : "foo" + + +d &&= 42 +>d &&= 42 : 0 | 42 | undefined +>d : number | undefined +>42 : 42 + +e ||= 42 +>e ||= 42 : number +>e : number | undefined +>42 : 42 + +f ??= 42 +>f ??= 42 : number +>f : number | undefined +>42 : 42 + +g &&= 42 +>g &&= 42 : 0 | 42 +>g : 0 | 1 | 42 +>42 : 42 + +h ||= 42 +>h ||= 42 : 1 | 42 +>h : 0 | 1 | 42 +>42 : 42 + +i ??= 42 +>i ??= 42 : 0 | 1 | 42 +>i : 0 | 1 | 42 +>42 : 42 + diff --git a/tests/baselines/reference/logicalAssignment2(target=es2015).js b/tests/baselines/reference/logicalAssignment2(target=es2015).js new file mode 100644 index 0000000000000..c5dbfbac49f05 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=es2015).js @@ -0,0 +1,43 @@ +//// [logicalAssignment2.ts] +interface A { + foo: { + bar(): { + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A +declare const a: A +declare const b: A +declare const c: A + +a.baz &&= result.baz +b.baz ||= result.baz +c.baz ??= result.baz + +a.foo["baz"] &&= result.foo.baz +b.foo["baz"] ||= result.foo.baz +c.foo["baz"] ??= result.foo.baz + +a.foo.bar().baz &&= result.foo.bar().baz +b.foo.bar().baz ||= result.foo.bar().baz +c.foo.bar().baz ??= result.foo.bar().baz + + + +//// [logicalAssignment2.js] +"use strict"; +var _a, _b, _c; +var _d, _e, _f, _g, _h, _j, _k, _l, _m; +(_d = a).baz && (_d.baz = result.baz); +(_e = b).baz || (_e.baz = result.baz); +(_a = (_f = c).baz) !== null && _a !== void 0 ? _a : (_f.baz = result.baz); +(_g = a.foo)["baz"] && (_g["baz"] = result.foo.baz); +(_h = b.foo)["baz"] || (_h["baz"] = result.foo.baz); +(_b = (_j = c.foo)["baz"]) !== null && _b !== void 0 ? _b : (_j["baz"] = result.foo.baz); +(_k = a.foo.bar()).baz && (_k.baz = result.foo.bar().baz); +(_l = b.foo.bar()).baz || (_l.baz = result.foo.bar().baz); +(_c = (_m = c.foo.bar()).baz) !== null && _c !== void 0 ? _c : (_m.baz = result.foo.bar().baz); diff --git a/tests/baselines/reference/logicalAssignment2(target=es2015).symbols b/tests/baselines/reference/logicalAssignment2(target=es2015).symbols new file mode 100644 index 0000000000000..503996af38772 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=es2015).symbols @@ -0,0 +1,142 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts === +interface A { +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + + foo: { +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) + + bar(): { +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) + + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + } + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + } + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +} + +declare const result: A +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const a: A +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const b: A +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const c: A +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +a.baz &&= result.baz +>a.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +b.baz ||= result.baz +>b.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +c.baz ??= result.baz +>c.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +a.foo["baz"] &&= result.foo.baz +>a.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +b.foo["baz"] ||= result.foo.baz +>b.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +c.foo["baz"] ??= result.foo.baz +>c.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +a.foo.bar().baz &&= result.foo.bar().baz +>a.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>a.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>a.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + +b.foo.bar().baz ||= result.foo.bar().baz +>b.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>b.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>b.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + +c.foo.bar().baz ??= result.foo.bar().baz +>c.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>c.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>c.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + + diff --git a/tests/baselines/reference/logicalAssignment2(target=es2015).types b/tests/baselines/reference/logicalAssignment2(target=es2015).types new file mode 100644 index 0000000000000..7f1a58aa3222e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=es2015).types @@ -0,0 +1,154 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts === +interface A { + foo: { +>foo : { bar(): { baz: 0 | 1 | 42 | undefined | '';}; baz: 0 | 1 | 42 | undefined | ''; } + + bar(): { +>bar : () => { baz: 0 | 1 | 42 | undefined | '';} + + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined + } + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined + } + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined +} + +declare const result: A +>result : A + +declare const a: A +>a : A + +declare const b: A +>b : A + +declare const c: A +>c : A + +a.baz &&= result.baz +>a.baz &&= result.baz : "" | 0 | 1 | 42 | undefined +>a.baz : "" | 0 | 1 | 42 | undefined +>a : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +b.baz ||= result.baz +>b.baz ||= result.baz : "" | 0 | 1 | 42 | undefined +>b.baz : "" | 0 | 1 | 42 | undefined +>b : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +c.baz ??= result.baz +>c.baz ??= result.baz : "" | 0 | 1 | 42 | undefined +>c.baz : "" | 0 | 1 | 42 | undefined +>c : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +a.foo["baz"] &&= result.foo.baz +>a.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined +>a.foo["baz"] : "" | 0 | 1 | 42 | undefined +>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>a : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +b.foo["baz"] ||= result.foo.baz +>b.foo["baz"] ||= result.foo.baz : "" | 0 | 1 | 42 | undefined +>b.foo["baz"] : "" | 0 | 1 | 42 | undefined +>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>b : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +c.foo["baz"] ??= result.foo.baz +>c.foo["baz"] ??= result.foo.baz : "" | 0 | 1 | 42 | undefined +>c.foo["baz"] : "" | 0 | 1 | 42 | undefined +>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>c : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +a.foo.bar().baz &&= result.foo.bar().baz +>a.foo.bar().baz &&= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>a.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>a.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>a.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>a : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +b.foo.bar().baz ||= result.foo.bar().baz +>b.foo.bar().baz ||= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>b.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>b.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>b.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>b : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +c.foo.bar().baz ??= result.foo.bar().baz +>c.foo.bar().baz ??= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>c.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>c.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>c.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>c : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + + diff --git a/tests/baselines/reference/logicalAssignment2(target=es2020).js b/tests/baselines/reference/logicalAssignment2(target=es2020).js new file mode 100644 index 0000000000000..fd285b64ad7c6 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=es2020).js @@ -0,0 +1,42 @@ +//// [logicalAssignment2.ts] +interface A { + foo: { + bar(): { + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A +declare const a: A +declare const b: A +declare const c: A + +a.baz &&= result.baz +b.baz ||= result.baz +c.baz ??= result.baz + +a.foo["baz"] &&= result.foo.baz +b.foo["baz"] ||= result.foo.baz +c.foo["baz"] ??= result.foo.baz + +a.foo.bar().baz &&= result.foo.bar().baz +b.foo.bar().baz ||= result.foo.bar().baz +c.foo.bar().baz ??= result.foo.bar().baz + + + +//// [logicalAssignment2.js] +"use strict"; +var _a, _b, _c, _d, _e, _f, _g, _h, _j; +(_a = a).baz && (_a.baz = result.baz); +(_b = b).baz || (_b.baz = result.baz); +(_c = c).baz ?? (_c.baz = result.baz); +(_d = a.foo)["baz"] && (_d["baz"] = result.foo.baz); +(_e = b.foo)["baz"] || (_e["baz"] = result.foo.baz); +(_f = c.foo)["baz"] ?? (_f["baz"] = result.foo.baz); +(_g = a.foo.bar()).baz && (_g.baz = result.foo.bar().baz); +(_h = b.foo.bar()).baz || (_h.baz = result.foo.bar().baz); +(_j = c.foo.bar()).baz ?? (_j.baz = result.foo.bar().baz); diff --git a/tests/baselines/reference/logicalAssignment2(target=es2020).symbols b/tests/baselines/reference/logicalAssignment2(target=es2020).symbols new file mode 100644 index 0000000000000..503996af38772 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=es2020).symbols @@ -0,0 +1,142 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts === +interface A { +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + + foo: { +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) + + bar(): { +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) + + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + } + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + } + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +} + +declare const result: A +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const a: A +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const b: A +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const c: A +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +a.baz &&= result.baz +>a.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +b.baz ||= result.baz +>b.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +c.baz ??= result.baz +>c.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +a.foo["baz"] &&= result.foo.baz +>a.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +b.foo["baz"] ||= result.foo.baz +>b.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +c.foo["baz"] ??= result.foo.baz +>c.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +a.foo.bar().baz &&= result.foo.bar().baz +>a.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>a.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>a.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + +b.foo.bar().baz ||= result.foo.bar().baz +>b.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>b.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>b.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + +c.foo.bar().baz ??= result.foo.bar().baz +>c.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>c.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>c.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + + diff --git a/tests/baselines/reference/logicalAssignment2(target=es2020).types b/tests/baselines/reference/logicalAssignment2(target=es2020).types new file mode 100644 index 0000000000000..7f1a58aa3222e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=es2020).types @@ -0,0 +1,154 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts === +interface A { + foo: { +>foo : { bar(): { baz: 0 | 1 | 42 | undefined | '';}; baz: 0 | 1 | 42 | undefined | ''; } + + bar(): { +>bar : () => { baz: 0 | 1 | 42 | undefined | '';} + + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined + } + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined + } + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined +} + +declare const result: A +>result : A + +declare const a: A +>a : A + +declare const b: A +>b : A + +declare const c: A +>c : A + +a.baz &&= result.baz +>a.baz &&= result.baz : "" | 0 | 1 | 42 | undefined +>a.baz : "" | 0 | 1 | 42 | undefined +>a : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +b.baz ||= result.baz +>b.baz ||= result.baz : "" | 0 | 1 | 42 | undefined +>b.baz : "" | 0 | 1 | 42 | undefined +>b : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +c.baz ??= result.baz +>c.baz ??= result.baz : "" | 0 | 1 | 42 | undefined +>c.baz : "" | 0 | 1 | 42 | undefined +>c : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +a.foo["baz"] &&= result.foo.baz +>a.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined +>a.foo["baz"] : "" | 0 | 1 | 42 | undefined +>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>a : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +b.foo["baz"] ||= result.foo.baz +>b.foo["baz"] ||= result.foo.baz : "" | 0 | 1 | 42 | undefined +>b.foo["baz"] : "" | 0 | 1 | 42 | undefined +>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>b : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +c.foo["baz"] ??= result.foo.baz +>c.foo["baz"] ??= result.foo.baz : "" | 0 | 1 | 42 | undefined +>c.foo["baz"] : "" | 0 | 1 | 42 | undefined +>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>c : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +a.foo.bar().baz &&= result.foo.bar().baz +>a.foo.bar().baz &&= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>a.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>a.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>a.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>a : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +b.foo.bar().baz ||= result.foo.bar().baz +>b.foo.bar().baz ||= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>b.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>b.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>b.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>b : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +c.foo.bar().baz ??= result.foo.bar().baz +>c.foo.bar().baz ??= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>c.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>c.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>c.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>c : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + + diff --git a/tests/baselines/reference/logicalAssignment2(target=esnext).js b/tests/baselines/reference/logicalAssignment2(target=esnext).js new file mode 100644 index 0000000000000..028fd724bc151 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=esnext).js @@ -0,0 +1,41 @@ +//// [logicalAssignment2.ts] +interface A { + foo: { + bar(): { + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A +declare const a: A +declare const b: A +declare const c: A + +a.baz &&= result.baz +b.baz ||= result.baz +c.baz ??= result.baz + +a.foo["baz"] &&= result.foo.baz +b.foo["baz"] ||= result.foo.baz +c.foo["baz"] ??= result.foo.baz + +a.foo.bar().baz &&= result.foo.bar().baz +b.foo.bar().baz ||= result.foo.bar().baz +c.foo.bar().baz ??= result.foo.bar().baz + + + +//// [logicalAssignment2.js] +"use strict"; +a.baz &&= result.baz; +b.baz ||= result.baz; +c.baz ??= result.baz; +a.foo["baz"] &&= result.foo.baz; +b.foo["baz"] ||= result.foo.baz; +c.foo["baz"] ??= result.foo.baz; +a.foo.bar().baz &&= result.foo.bar().baz; +b.foo.bar().baz ||= result.foo.bar().baz; +c.foo.bar().baz ??= result.foo.bar().baz; diff --git a/tests/baselines/reference/logicalAssignment2(target=esnext).symbols b/tests/baselines/reference/logicalAssignment2(target=esnext).symbols new file mode 100644 index 0000000000000..503996af38772 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=esnext).symbols @@ -0,0 +1,142 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts === +interface A { +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + + foo: { +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) + + bar(): { +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) + + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + } + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + } + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +} + +declare const result: A +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const a: A +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const b: A +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +declare const c: A +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>A : Symbol(A, Decl(logicalAssignment2.ts, 0, 0)) + +a.baz &&= result.baz +>a.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +b.baz ||= result.baz +>b.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +c.baz ??= result.baz +>c.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment2.ts, 6, 5)) + +a.foo["baz"] &&= result.foo.baz +>a.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +b.foo["baz"] ||= result.foo.baz +>b.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +c.foo["baz"] ??= result.foo.baz +>c.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>"baz" : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo.baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 4, 9)) + +a.foo.bar().baz &&= result.foo.bar().baz +>a.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>a.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>a.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment2.ts, 11, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + +b.foo.bar().baz ||= result.foo.bar().baz +>b.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>b.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>b.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment2.ts, 12, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + +c.foo.bar().baz ??= result.foo.bar().baz +>c.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>c.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>c.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment2.ts, 13, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar().baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) +>result.foo.bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>result.foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment2.ts, 10, 13)) +>foo : Symbol(A.foo, Decl(logicalAssignment2.ts, 0, 13)) +>bar : Symbol(bar, Decl(logicalAssignment2.ts, 1, 10)) +>baz : Symbol(baz, Decl(logicalAssignment2.ts, 2, 16)) + + diff --git a/tests/baselines/reference/logicalAssignment2(target=esnext).types b/tests/baselines/reference/logicalAssignment2(target=esnext).types new file mode 100644 index 0000000000000..7f1a58aa3222e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment2(target=esnext).types @@ -0,0 +1,154 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts === +interface A { + foo: { +>foo : { bar(): { baz: 0 | 1 | 42 | undefined | '';}; baz: 0 | 1 | 42 | undefined | ''; } + + bar(): { +>bar : () => { baz: 0 | 1 | 42 | undefined | '';} + + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined + } + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined + } + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined +} + +declare const result: A +>result : A + +declare const a: A +>a : A + +declare const b: A +>b : A + +declare const c: A +>c : A + +a.baz &&= result.baz +>a.baz &&= result.baz : "" | 0 | 1 | 42 | undefined +>a.baz : "" | 0 | 1 | 42 | undefined +>a : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +b.baz ||= result.baz +>b.baz ||= result.baz : "" | 0 | 1 | 42 | undefined +>b.baz : "" | 0 | 1 | 42 | undefined +>b : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +c.baz ??= result.baz +>c.baz ??= result.baz : "" | 0 | 1 | 42 | undefined +>c.baz : "" | 0 | 1 | 42 | undefined +>c : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +a.foo["baz"] &&= result.foo.baz +>a.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined +>a.foo["baz"] : "" | 0 | 1 | 42 | undefined +>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>a : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +b.foo["baz"] ||= result.foo.baz +>b.foo["baz"] ||= result.foo.baz : "" | 0 | 1 | 42 | undefined +>b.foo["baz"] : "" | 0 | 1 | 42 | undefined +>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>b : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +c.foo["baz"] ??= result.foo.baz +>c.foo["baz"] ??= result.foo.baz : "" | 0 | 1 | 42 | undefined +>c.foo["baz"] : "" | 0 | 1 | 42 | undefined +>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>c : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>"baz" : "baz" +>result.foo.baz : "" | 0 | 1 | 42 | undefined +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +a.foo.bar().baz &&= result.foo.bar().baz +>a.foo.bar().baz &&= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>a.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>a.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>a.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>a : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +b.foo.bar().baz ||= result.foo.bar().baz +>b.foo.bar().baz ||= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>b.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>b.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>b.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>b : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + +c.foo.bar().baz ??= result.foo.bar().baz +>c.foo.bar().baz ??= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>c.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>c.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>c.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>c : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined +>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>result.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>result : A +>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; } +>bar : () => { baz: "" | 0 | 1 | 42 | undefined; } +>baz : "" | 0 | 1 | 42 | undefined + + diff --git a/tests/baselines/reference/logicalAssignment3(target=es2015).js b/tests/baselines/reference/logicalAssignment3(target=es2015).js new file mode 100644 index 0000000000000..47f0a210412e1 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=es2015).js @@ -0,0 +1,23 @@ +//// [logicalAssignment3.ts] +interface A { + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A; +declare const a: A; +declare const b: A; +declare const c: A; + +(a.baz) &&= result.baz; +(b.baz) ||= result.baz; +(c.baz) ??= result.baz; + + + +//// [logicalAssignment3.js] +"use strict"; +var _a; +var _b, _c, _d; +(_b = a).baz && (_b.baz = result.baz); +(_c = b).baz || (_c.baz = result.baz); +(_a = (_d = c).baz) !== null && _a !== void 0 ? _a : (_d.baz = result.baz); diff --git a/tests/baselines/reference/logicalAssignment3(target=es2015).symbols b/tests/baselines/reference/logicalAssignment3(target=es2015).symbols new file mode 100644 index 0000000000000..5d17ac406b683 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=es2015).symbols @@ -0,0 +1,49 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts === +interface A { +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +} + +declare const result: A; +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const a: A; +>a : Symbol(a, Decl(logicalAssignment3.ts, 5, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const b: A; +>b : Symbol(b, Decl(logicalAssignment3.ts, 6, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const c: A; +>c : Symbol(c, Decl(logicalAssignment3.ts, 7, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +(a.baz) &&= result.baz; +>a.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment3.ts, 5, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + +(b.baz) ||= result.baz; +>b.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment3.ts, 6, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + +(c.baz) ??= result.baz; +>c.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment3.ts, 7, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + + diff --git a/tests/baselines/reference/logicalAssignment3(target=es2015).types b/tests/baselines/reference/logicalAssignment3(target=es2015).types new file mode 100644 index 0000000000000..34ee2dc390129 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=es2015).types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts === +interface A { + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined +} + +declare const result: A; +>result : A + +declare const a: A; +>a : A + +declare const b: A; +>b : A + +declare const c: A; +>c : A + +(a.baz) &&= result.baz; +>(a.baz) &&= result.baz : "" | 0 | 1 | 42 | undefined +>(a.baz) : "" | 0 | 1 | 42 | undefined +>a.baz : "" | 0 | 1 | 42 | undefined +>a : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +(b.baz) ||= result.baz; +>(b.baz) ||= result.baz : "" | 0 | 1 | 42 | undefined +>(b.baz) : "" | 0 | 1 | 42 | undefined +>b.baz : "" | 0 | 1 | 42 | undefined +>b : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +(c.baz) ??= result.baz; +>(c.baz) ??= result.baz : "" | 0 | 1 | 42 | undefined +>(c.baz) : "" | 0 | 1 | 42 | undefined +>c.baz : "" | 0 | 1 | 42 | undefined +>c : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + + diff --git a/tests/baselines/reference/logicalAssignment3(target=es2020).js b/tests/baselines/reference/logicalAssignment3(target=es2020).js new file mode 100644 index 0000000000000..57060aea11685 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=es2020).js @@ -0,0 +1,22 @@ +//// [logicalAssignment3.ts] +interface A { + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A; +declare const a: A; +declare const b: A; +declare const c: A; + +(a.baz) &&= result.baz; +(b.baz) ||= result.baz; +(c.baz) ??= result.baz; + + + +//// [logicalAssignment3.js] +"use strict"; +var _a, _b, _c; +(_a = a).baz && (_a.baz = result.baz); +(_b = b).baz || (_b.baz = result.baz); +(_c = c).baz ?? (_c.baz = result.baz); diff --git a/tests/baselines/reference/logicalAssignment3(target=es2020).symbols b/tests/baselines/reference/logicalAssignment3(target=es2020).symbols new file mode 100644 index 0000000000000..5d17ac406b683 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=es2020).symbols @@ -0,0 +1,49 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts === +interface A { +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +} + +declare const result: A; +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const a: A; +>a : Symbol(a, Decl(logicalAssignment3.ts, 5, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const b: A; +>b : Symbol(b, Decl(logicalAssignment3.ts, 6, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const c: A; +>c : Symbol(c, Decl(logicalAssignment3.ts, 7, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +(a.baz) &&= result.baz; +>a.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment3.ts, 5, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + +(b.baz) ||= result.baz; +>b.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment3.ts, 6, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + +(c.baz) ??= result.baz; +>c.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment3.ts, 7, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + + diff --git a/tests/baselines/reference/logicalAssignment3(target=es2020).types b/tests/baselines/reference/logicalAssignment3(target=es2020).types new file mode 100644 index 0000000000000..34ee2dc390129 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=es2020).types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts === +interface A { + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined +} + +declare const result: A; +>result : A + +declare const a: A; +>a : A + +declare const b: A; +>b : A + +declare const c: A; +>c : A + +(a.baz) &&= result.baz; +>(a.baz) &&= result.baz : "" | 0 | 1 | 42 | undefined +>(a.baz) : "" | 0 | 1 | 42 | undefined +>a.baz : "" | 0 | 1 | 42 | undefined +>a : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +(b.baz) ||= result.baz; +>(b.baz) ||= result.baz : "" | 0 | 1 | 42 | undefined +>(b.baz) : "" | 0 | 1 | 42 | undefined +>b.baz : "" | 0 | 1 | 42 | undefined +>b : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +(c.baz) ??= result.baz; +>(c.baz) ??= result.baz : "" | 0 | 1 | 42 | undefined +>(c.baz) : "" | 0 | 1 | 42 | undefined +>c.baz : "" | 0 | 1 | 42 | undefined +>c : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + + diff --git a/tests/baselines/reference/logicalAssignment3(target=esnext).js b/tests/baselines/reference/logicalAssignment3(target=esnext).js new file mode 100644 index 0000000000000..113bdd39d3f19 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=esnext).js @@ -0,0 +1,21 @@ +//// [logicalAssignment3.ts] +interface A { + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A; +declare const a: A; +declare const b: A; +declare const c: A; + +(a.baz) &&= result.baz; +(b.baz) ||= result.baz; +(c.baz) ??= result.baz; + + + +//// [logicalAssignment3.js] +"use strict"; +(a.baz) &&= result.baz; +(b.baz) ||= result.baz; +(c.baz) ??= result.baz; diff --git a/tests/baselines/reference/logicalAssignment3(target=esnext).symbols b/tests/baselines/reference/logicalAssignment3(target=esnext).symbols new file mode 100644 index 0000000000000..5d17ac406b683 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=esnext).symbols @@ -0,0 +1,49 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts === +interface A { +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + + baz: 0 | 1 | 42 | undefined | '' +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +} + +declare const result: A; +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const a: A; +>a : Symbol(a, Decl(logicalAssignment3.ts, 5, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const b: A; +>b : Symbol(b, Decl(logicalAssignment3.ts, 6, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +declare const c: A; +>c : Symbol(c, Decl(logicalAssignment3.ts, 7, 13)) +>A : Symbol(A, Decl(logicalAssignment3.ts, 0, 0)) + +(a.baz) &&= result.baz; +>a.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>a : Symbol(a, Decl(logicalAssignment3.ts, 5, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + +(b.baz) ||= result.baz; +>b.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>b : Symbol(b, Decl(logicalAssignment3.ts, 6, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + +(c.baz) ??= result.baz; +>c.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>c : Symbol(c, Decl(logicalAssignment3.ts, 7, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result.baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) +>result : Symbol(result, Decl(logicalAssignment3.ts, 4, 13)) +>baz : Symbol(A.baz, Decl(logicalAssignment3.ts, 0, 13)) + + diff --git a/tests/baselines/reference/logicalAssignment3(target=esnext).types b/tests/baselines/reference/logicalAssignment3(target=esnext).types new file mode 100644 index 0000000000000..34ee2dc390129 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment3(target=esnext).types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts === +interface A { + baz: 0 | 1 | 42 | undefined | '' +>baz : "" | 0 | 1 | 42 | undefined +} + +declare const result: A; +>result : A + +declare const a: A; +>a : A + +declare const b: A; +>b : A + +declare const c: A; +>c : A + +(a.baz) &&= result.baz; +>(a.baz) &&= result.baz : "" | 0 | 1 | 42 | undefined +>(a.baz) : "" | 0 | 1 | 42 | undefined +>a.baz : "" | 0 | 1 | 42 | undefined +>a : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +(b.baz) ||= result.baz; +>(b.baz) ||= result.baz : "" | 0 | 1 | 42 | undefined +>(b.baz) : "" | 0 | 1 | 42 | undefined +>b.baz : "" | 0 | 1 | 42 | undefined +>b : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + +(c.baz) ??= result.baz; +>(c.baz) ??= result.baz : "" | 0 | 1 | 42 | undefined +>(c.baz) : "" | 0 | 1 | 42 | undefined +>c.baz : "" | 0 | 1 | 42 | undefined +>c : A +>baz : "" | 0 | 1 | 42 | undefined +>result.baz : "" | 0 | 1 | 42 | undefined +>result : A +>baz : "" | 0 | 1 | 42 | undefined + + diff --git a/tests/baselines/reference/logicalAssignment4(target=es2015).errors.txt b/tests/baselines/reference/logicalAssignment4(target=es2015).errors.txt new file mode 100644 index 0000000000000..ee34fac607c33 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2015).errors.txt @@ -0,0 +1,57 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(39,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(45,13): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (2 errors) ==== + function foo1(results: number[] | undefined) { + (results ||= []).push(100); + } + + function foo2(results: number[] | undefined) { + (results ??= []).push(100); + } + + function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); + } + + function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); + } + + interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal + } + declare const v: number + function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + ~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + ~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment4(target=es2015).js b/tests/baselines/reference/logicalAssignment4(target=es2015).js new file mode 100644 index 0000000000000..b54bfb6d48796 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2015).js @@ -0,0 +1,91 @@ +//// [logicalAssignment4.ts] +function foo1(results: number[] | undefined) { + (results ||= []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= []).push(100); +} + +function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); +} + +function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); +} + +interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal +} +declare const v: number +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + } + } +} + +//// [logicalAssignment4.js] +"use strict"; +function foo1(results) { + (results || (results = [])).push(100); +} +function foo2(results) { + (results !== null && results !== void 0 ? results : (results = [])).push(100); +} +function foo3(results) { + results || (results = []); + results.push(100); +} +function foo4(results) { + results !== null && results !== void 0 ? results : (results = []); + results.push(100); +} +function doSomethingWithAlias(thing, defaultValue) { + if (v === 1) { + if (thing && (thing = thing.original)) { + thing.name; + } + } + else if (v === 2) { + if (thing && (thing = defaultValue)) { + thing.name; + defaultValue.name; + } + } + else if (v === 3) { + if (thing || (thing = defaultValue)) { + thing.name; + defaultValue.name; + } + } + else { + if (thing !== null && thing !== void 0 ? thing : (thing = defaultValue)) { + thing.name; + defaultValue.name; + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=es2015).symbols b/tests/baselines/reference/logicalAssignment4(target=es2015).symbols new file mode 100644 index 0000000000000..46a02a4811074 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2015).symbols @@ -0,0 +1,135 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts === +function foo1(results: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment4.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 0, 14)) + + (results ||= []).push(100); +>(results ||= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 0, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment4.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 4, 14)) + + (results ??= []).push(100); +>(results ??= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 4, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment4.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) + + results ||= []; +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) + + results.push(100); +>results.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo4(results: number[] | undefined) { +>foo4 : Symbol(foo4, Decl(logicalAssignment4.ts, 11, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) + + results ??= []; +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) + + results.push(100); +>results.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +interface ThingWithOriginal { +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) + + name: string; +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + original?: ThingWithOriginal +>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) +} +declare const v: number +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { +>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 22, 23)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) + + if (v === 1) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing &&= thing.original) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>thing.original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else if (v === 2) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing &&= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else if (v === 3) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing ||= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name; +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else { + if (thing ??= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name; +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=es2015).types b/tests/baselines/reference/logicalAssignment4(target=es2015).types new file mode 100644 index 0000000000000..6a044ae0e1bf2 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2015).types @@ -0,0 +1,158 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts === +function foo1(results: number[] | undefined) { +>foo1 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ||= []).push(100); +>(results ||= []).push(100) : number +>(results ||= []).push : (...items: number[]) => number +>(results ||= []) : number[] +>results ||= [] : number[] +>results : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined) { +>foo2 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ??= []).push(100); +>(results ??= []).push(100) : number +>(results ??= []).push : (...items: number[]) => number +>(results ??= []) : number[] +>results ??= [] : number[] +>results : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined) { +>foo3 : (results: number[] | undefined) => void +>results : number[] | undefined + + results ||= []; +>results ||= [] : number[] +>results : number[] | undefined +>[] : never[] + + results.push(100); +>results.push(100) : number +>results.push : (...items: number[]) => number +>results : number[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo4(results: number[] | undefined) { +>foo4 : (results: number[] | undefined) => void +>results : number[] | undefined + + results ??= []; +>results ??= [] : number[] +>results : number[] | undefined +>[] : never[] + + results.push(100); +>results.push(100) : number +>results.push : (...items: number[]) => number +>results : number[] +>push : (...items: number[]) => number +>100 : 100 +} + +interface ThingWithOriginal { + name: string; +>name : string + + original?: ThingWithOriginal +>original : ThingWithOriginal | undefined +} +declare const v: number +>v : number + +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { +>doSomethingWithAlias : (thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) => void +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + if (v === 1) { +>v === 1 : boolean +>v : number +>1 : 1 + + if (thing &&= thing.original) { +>thing &&= thing.original : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>thing.original : ThingWithOriginal | undefined +>thing : ThingWithOriginal +>original : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + } + } + else if (v === 2) { +>v === 2 : boolean +>v : number +>2 : 2 + + if (thing &&= defaultValue) { +>thing &&= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name +>defaultValue.name : string +>defaultValue : ThingWithOriginal +>name : string + } + } + else if (v === 3) { +>v === 3 : boolean +>v : number +>3 : 3 + + if (thing ||= defaultValue) { +>thing ||= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name; +>defaultValue.name : string +>defaultValue : ThingWithOriginal | undefined +>name : string + } + } + else { + if (thing ??= defaultValue) { +>thing ??= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name; +>defaultValue.name : string +>defaultValue : ThingWithOriginal | undefined +>name : string + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=es2020).errors.txt b/tests/baselines/reference/logicalAssignment4(target=es2020).errors.txt new file mode 100644 index 0000000000000..ee34fac607c33 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2020).errors.txt @@ -0,0 +1,57 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(39,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(45,13): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (2 errors) ==== + function foo1(results: number[] | undefined) { + (results ||= []).push(100); + } + + function foo2(results: number[] | undefined) { + (results ??= []).push(100); + } + + function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); + } + + function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); + } + + interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal + } + declare const v: number + function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + ~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + ~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment4(target=es2020).js b/tests/baselines/reference/logicalAssignment4(target=es2020).js new file mode 100644 index 0000000000000..b2dc9ae3ce941 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2020).js @@ -0,0 +1,91 @@ +//// [logicalAssignment4.ts] +function foo1(results: number[] | undefined) { + (results ||= []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= []).push(100); +} + +function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); +} + +function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); +} + +interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal +} +declare const v: number +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + } + } +} + +//// [logicalAssignment4.js] +"use strict"; +function foo1(results) { + (results || (results = [])).push(100); +} +function foo2(results) { + (results ?? (results = [])).push(100); +} +function foo3(results) { + results || (results = []); + results.push(100); +} +function foo4(results) { + results ?? (results = []); + results.push(100); +} +function doSomethingWithAlias(thing, defaultValue) { + if (v === 1) { + if (thing && (thing = thing.original)) { + thing.name; + } + } + else if (v === 2) { + if (thing && (thing = defaultValue)) { + thing.name; + defaultValue.name; + } + } + else if (v === 3) { + if (thing || (thing = defaultValue)) { + thing.name; + defaultValue.name; + } + } + else { + if (thing ?? (thing = defaultValue)) { + thing.name; + defaultValue.name; + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=es2020).symbols b/tests/baselines/reference/logicalAssignment4(target=es2020).symbols new file mode 100644 index 0000000000000..46a02a4811074 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2020).symbols @@ -0,0 +1,135 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts === +function foo1(results: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment4.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 0, 14)) + + (results ||= []).push(100); +>(results ||= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 0, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment4.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 4, 14)) + + (results ??= []).push(100); +>(results ??= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 4, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment4.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) + + results ||= []; +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) + + results.push(100); +>results.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo4(results: number[] | undefined) { +>foo4 : Symbol(foo4, Decl(logicalAssignment4.ts, 11, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) + + results ??= []; +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) + + results.push(100); +>results.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +interface ThingWithOriginal { +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) + + name: string; +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + original?: ThingWithOriginal +>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) +} +declare const v: number +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { +>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 22, 23)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) + + if (v === 1) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing &&= thing.original) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>thing.original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else if (v === 2) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing &&= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else if (v === 3) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing ||= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name; +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else { + if (thing ??= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name; +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=es2020).types b/tests/baselines/reference/logicalAssignment4(target=es2020).types new file mode 100644 index 0000000000000..6a044ae0e1bf2 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=es2020).types @@ -0,0 +1,158 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts === +function foo1(results: number[] | undefined) { +>foo1 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ||= []).push(100); +>(results ||= []).push(100) : number +>(results ||= []).push : (...items: number[]) => number +>(results ||= []) : number[] +>results ||= [] : number[] +>results : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined) { +>foo2 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ??= []).push(100); +>(results ??= []).push(100) : number +>(results ??= []).push : (...items: number[]) => number +>(results ??= []) : number[] +>results ??= [] : number[] +>results : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined) { +>foo3 : (results: number[] | undefined) => void +>results : number[] | undefined + + results ||= []; +>results ||= [] : number[] +>results : number[] | undefined +>[] : never[] + + results.push(100); +>results.push(100) : number +>results.push : (...items: number[]) => number +>results : number[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo4(results: number[] | undefined) { +>foo4 : (results: number[] | undefined) => void +>results : number[] | undefined + + results ??= []; +>results ??= [] : number[] +>results : number[] | undefined +>[] : never[] + + results.push(100); +>results.push(100) : number +>results.push : (...items: number[]) => number +>results : number[] +>push : (...items: number[]) => number +>100 : 100 +} + +interface ThingWithOriginal { + name: string; +>name : string + + original?: ThingWithOriginal +>original : ThingWithOriginal | undefined +} +declare const v: number +>v : number + +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { +>doSomethingWithAlias : (thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) => void +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + if (v === 1) { +>v === 1 : boolean +>v : number +>1 : 1 + + if (thing &&= thing.original) { +>thing &&= thing.original : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>thing.original : ThingWithOriginal | undefined +>thing : ThingWithOriginal +>original : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + } + } + else if (v === 2) { +>v === 2 : boolean +>v : number +>2 : 2 + + if (thing &&= defaultValue) { +>thing &&= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name +>defaultValue.name : string +>defaultValue : ThingWithOriginal +>name : string + } + } + else if (v === 3) { +>v === 3 : boolean +>v : number +>3 : 3 + + if (thing ||= defaultValue) { +>thing ||= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name; +>defaultValue.name : string +>defaultValue : ThingWithOriginal | undefined +>name : string + } + } + else { + if (thing ??= defaultValue) { +>thing ??= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name; +>defaultValue.name : string +>defaultValue : ThingWithOriginal | undefined +>name : string + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=esnext).errors.txt b/tests/baselines/reference/logicalAssignment4(target=esnext).errors.txt new file mode 100644 index 0000000000000..ee34fac607c33 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=esnext).errors.txt @@ -0,0 +1,57 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(39,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(45,13): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (2 errors) ==== + function foo1(results: number[] | undefined) { + (results ||= []).push(100); + } + + function foo2(results: number[] | undefined) { + (results ??= []).push(100); + } + + function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); + } + + function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); + } + + interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal + } + declare const v: number + function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + ~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + ~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment4(target=esnext).js b/tests/baselines/reference/logicalAssignment4(target=esnext).js new file mode 100644 index 0000000000000..5724bcaa58b1d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=esnext).js @@ -0,0 +1,91 @@ +//// [logicalAssignment4.ts] +function foo1(results: number[] | undefined) { + (results ||= []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= []).push(100); +} + +function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); +} + +function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); +} + +interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal +} +declare const v: number +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + } + } +} + +//// [logicalAssignment4.js] +"use strict"; +function foo1(results) { + (results ||= []).push(100); +} +function foo2(results) { + (results ??= []).push(100); +} +function foo3(results) { + results ||= []; + results.push(100); +} +function foo4(results) { + results ??= []; + results.push(100); +} +function doSomethingWithAlias(thing, defaultValue) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name; + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=esnext).symbols b/tests/baselines/reference/logicalAssignment4(target=esnext).symbols new file mode 100644 index 0000000000000..46a02a4811074 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=esnext).symbols @@ -0,0 +1,135 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts === +function foo1(results: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment4.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 0, 14)) + + (results ||= []).push(100); +>(results ||= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 0, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment4.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 4, 14)) + + (results ??= []).push(100); +>(results ??= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 4, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment4.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) + + results ||= []; +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) + + results.push(100); +>results.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 8, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo4(results: number[] | undefined) { +>foo4 : Symbol(foo4, Decl(logicalAssignment4.ts, 11, 1)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) + + results ??= []; +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) + + results.push(100); +>results.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment4.ts, 13, 14)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +interface ThingWithOriginal { +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) + + name: string; +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + original?: ThingWithOriginal +>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) +} +declare const v: number +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { +>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 22, 23)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1)) + + if (v === 1) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing &&= thing.original) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>thing.original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else if (v === 2) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing &&= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else if (v === 3) { +>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13)) + + if (thing ||= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name; +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } + else { + if (thing ??= defaultValue) { +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) + + thing.name; +>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + + defaultValue.name; +>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) +>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67)) +>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29)) + } + } +} diff --git a/tests/baselines/reference/logicalAssignment4(target=esnext).types b/tests/baselines/reference/logicalAssignment4(target=esnext).types new file mode 100644 index 0000000000000..6a044ae0e1bf2 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment4(target=esnext).types @@ -0,0 +1,158 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts === +function foo1(results: number[] | undefined) { +>foo1 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ||= []).push(100); +>(results ||= []).push(100) : number +>(results ||= []).push : (...items: number[]) => number +>(results ||= []) : number[] +>results ||= [] : number[] +>results : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined) { +>foo2 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ??= []).push(100); +>(results ??= []).push(100) : number +>(results ??= []).push : (...items: number[]) => number +>(results ??= []) : number[] +>results ??= [] : number[] +>results : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined) { +>foo3 : (results: number[] | undefined) => void +>results : number[] | undefined + + results ||= []; +>results ||= [] : number[] +>results : number[] | undefined +>[] : never[] + + results.push(100); +>results.push(100) : number +>results.push : (...items: number[]) => number +>results : number[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo4(results: number[] | undefined) { +>foo4 : (results: number[] | undefined) => void +>results : number[] | undefined + + results ??= []; +>results ??= [] : number[] +>results : number[] | undefined +>[] : never[] + + results.push(100); +>results.push(100) : number +>results.push : (...items: number[]) => number +>results : number[] +>push : (...items: number[]) => number +>100 : 100 +} + +interface ThingWithOriginal { + name: string; +>name : string + + original?: ThingWithOriginal +>original : ThingWithOriginal | undefined +} +declare const v: number +>v : number + +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { +>doSomethingWithAlias : (thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) => void +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + if (v === 1) { +>v === 1 : boolean +>v : number +>1 : 1 + + if (thing &&= thing.original) { +>thing &&= thing.original : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>thing.original : ThingWithOriginal | undefined +>thing : ThingWithOriginal +>original : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + } + } + else if (v === 2) { +>v === 2 : boolean +>v : number +>2 : 2 + + if (thing &&= defaultValue) { +>thing &&= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name +>defaultValue.name : string +>defaultValue : ThingWithOriginal +>name : string + } + } + else if (v === 3) { +>v === 3 : boolean +>v : number +>3 : 3 + + if (thing ||= defaultValue) { +>thing ||= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name; +>defaultValue.name : string +>defaultValue : ThingWithOriginal | undefined +>name : string + } + } + else { + if (thing ??= defaultValue) { +>thing ??= defaultValue : ThingWithOriginal | undefined +>thing : ThingWithOriginal | undefined +>defaultValue : ThingWithOriginal | undefined + + thing.name; +>thing.name : string +>thing : ThingWithOriginal +>name : string + + defaultValue.name; +>defaultValue.name : string +>defaultValue : ThingWithOriginal | undefined +>name : string + } + } +} diff --git a/tests/baselines/reference/logicalAssignment5(target=es2015).errors.txt b/tests/baselines/reference/logicalAssignment5(target=es2015).errors.txt new file mode 100644 index 0000000000000..8e9760990b033 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2015).errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(13,5): error TS2722: Cannot invoke an object which is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(17,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(22,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(28,5): error TS2722: Cannot invoke an object which is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts (4 errors) ==== + function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) + } + + function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) + } + + function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) + ~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + } + + function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + ~ +!!! error TS2532: Object is possibly 'undefined'. + f(42) + } + + function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + ~ +!!! error TS2532: Object is possibly 'undefined'. + f(42) + } + + function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) + ~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment5(target=es2015).js b/tests/baselines/reference/logicalAssignment5(target=es2015).js new file mode 100644 index 0000000000000..06fe4df0fe4e0 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2015).js @@ -0,0 +1,58 @@ +//// [logicalAssignment5.ts] +function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) +} + +function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) +} + +function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) +} + +function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + f(42) +} + +function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + f(42) +} + +function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) +} + + +//// [logicalAssignment5.js] +"use strict"; +function foo1(f) { + f !== null && f !== void 0 ? f : (f = a => a); + f(42); +} +function foo2(f) { + f || (f = a => a); + f(42); +} +function foo3(f) { + f && (f = a => a); + f(42); +} +function bar1(f) { + f !== null && f !== void 0 ? f : (f = (f.toString(), (a => a))); + f(42); +} +function bar2(f) { + f || (f = (f.toString(), (a => a))); + f(42); +} +function bar3(f) { + f && (f = (f.toString(), (a => a))); + f(42); +} diff --git a/tests/baselines/reference/logicalAssignment5(target=es2015).symbols b/tests/baselines/reference/logicalAssignment5(target=es2015).symbols new file mode 100644 index 0000000000000..5862d6b68d406 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2015).symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts === +function foo1 (f?: (a: number) => void) { +>foo1 : Symbol(foo1, Decl(logicalAssignment5.ts, 0, 0)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 0, 20)) + + f ??= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 1, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 1, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +} + +function foo2 (f?: (a: number) => void) { +>foo2 : Symbol(foo2, Decl(logicalAssignment5.ts, 3, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 5, 20)) + + f ||= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 6, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 6, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +} + +function foo3 (f?: (a: number) => void) { +>foo3 : Symbol(foo3, Decl(logicalAssignment5.ts, 8, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 10, 20)) + + f &&= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 11, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 11, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +} + +function bar1 (f?: (a: number) => void) { +>bar1 : Symbol(bar1, Decl(logicalAssignment5.ts, 13, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 15, 20)) + + f ??= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 16, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 16, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +} + +function bar2 (f?: (a: number) => void) { +>bar2 : Symbol(bar2, Decl(logicalAssignment5.ts, 18, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 20, 20)) + + f ||= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 21, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 21, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +} + +function bar3 (f?: (a: number) => void) { +>bar3 : Symbol(bar3, Decl(logicalAssignment5.ts, 23, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 25, 20)) + + f &&= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>f.toString : Symbol(Function.toString, Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>toString : Symbol(Function.toString, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 26, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 26, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +} + diff --git a/tests/baselines/reference/logicalAssignment5(target=es2015).types b/tests/baselines/reference/logicalAssignment5(target=es2015).types new file mode 100644 index 0000000000000..6ffb9b65a123e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2015).types @@ -0,0 +1,133 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts === +function foo1 (f?: (a: number) => void) { +>foo1 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ??= (a => a) +>f ??= (a => a) : (a: number) => void +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function foo2 (f?: (a: number) => void) { +>foo2 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ||= (a => a) +>f ||= (a => a) : (a: number) => void +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function foo3 (f?: (a: number) => void) { +>foo3 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f &&= (a => a) +>f &&= (a => a) : ((a: number) => number) | undefined +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : ((a: number) => void) | undefined +>42 : 42 +} + +function bar1 (f?: (a: number) => void) { +>bar1 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ??= (f.toString(), (a => a)) +>f ??= (f.toString(), (a => a)) : (a: number) => void +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : any +>f.toString : any +>f : undefined +>toString : any +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function bar2 (f?: (a: number) => void) { +>bar2 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ||= (f.toString(), (a => a)) +>f ||= (f.toString(), (a => a)) : (a: number) => void +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : any +>f.toString : any +>f : undefined +>toString : any +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function bar3 (f?: (a: number) => void) { +>bar3 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f &&= (f.toString(), (a => a)) +>f &&= (f.toString(), (a => a)) : ((a: number) => number) | undefined +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : string +>f.toString : () => string +>f : (a: number) => void +>toString : () => string +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : ((a: number) => void) | undefined +>42 : 42 +} + diff --git a/tests/baselines/reference/logicalAssignment5(target=es2020).errors.txt b/tests/baselines/reference/logicalAssignment5(target=es2020).errors.txt new file mode 100644 index 0000000000000..8e9760990b033 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2020).errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(13,5): error TS2722: Cannot invoke an object which is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(17,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(22,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(28,5): error TS2722: Cannot invoke an object which is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts (4 errors) ==== + function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) + } + + function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) + } + + function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) + ~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + } + + function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + ~ +!!! error TS2532: Object is possibly 'undefined'. + f(42) + } + + function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + ~ +!!! error TS2532: Object is possibly 'undefined'. + f(42) + } + + function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) + ~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment5(target=es2020).js b/tests/baselines/reference/logicalAssignment5(target=es2020).js new file mode 100644 index 0000000000000..4403e390b8eb9 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2020).js @@ -0,0 +1,58 @@ +//// [logicalAssignment5.ts] +function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) +} + +function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) +} + +function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) +} + +function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + f(42) +} + +function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + f(42) +} + +function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) +} + + +//// [logicalAssignment5.js] +"use strict"; +function foo1(f) { + f ?? (f = a => a); + f(42); +} +function foo2(f) { + f || (f = a => a); + f(42); +} +function foo3(f) { + f && (f = a => a); + f(42); +} +function bar1(f) { + f ?? (f = (f.toString(), (a => a))); + f(42); +} +function bar2(f) { + f || (f = (f.toString(), (a => a))); + f(42); +} +function bar3(f) { + f && (f = (f.toString(), (a => a))); + f(42); +} diff --git a/tests/baselines/reference/logicalAssignment5(target=es2020).symbols b/tests/baselines/reference/logicalAssignment5(target=es2020).symbols new file mode 100644 index 0000000000000..5862d6b68d406 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2020).symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts === +function foo1 (f?: (a: number) => void) { +>foo1 : Symbol(foo1, Decl(logicalAssignment5.ts, 0, 0)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 0, 20)) + + f ??= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 1, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 1, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +} + +function foo2 (f?: (a: number) => void) { +>foo2 : Symbol(foo2, Decl(logicalAssignment5.ts, 3, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 5, 20)) + + f ||= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 6, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 6, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +} + +function foo3 (f?: (a: number) => void) { +>foo3 : Symbol(foo3, Decl(logicalAssignment5.ts, 8, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 10, 20)) + + f &&= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 11, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 11, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +} + +function bar1 (f?: (a: number) => void) { +>bar1 : Symbol(bar1, Decl(logicalAssignment5.ts, 13, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 15, 20)) + + f ??= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 16, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 16, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +} + +function bar2 (f?: (a: number) => void) { +>bar2 : Symbol(bar2, Decl(logicalAssignment5.ts, 18, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 20, 20)) + + f ||= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 21, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 21, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +} + +function bar3 (f?: (a: number) => void) { +>bar3 : Symbol(bar3, Decl(logicalAssignment5.ts, 23, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 25, 20)) + + f &&= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>f.toString : Symbol(Function.toString, Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>toString : Symbol(Function.toString, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 26, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 26, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +} + diff --git a/tests/baselines/reference/logicalAssignment5(target=es2020).types b/tests/baselines/reference/logicalAssignment5(target=es2020).types new file mode 100644 index 0000000000000..6ffb9b65a123e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=es2020).types @@ -0,0 +1,133 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts === +function foo1 (f?: (a: number) => void) { +>foo1 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ??= (a => a) +>f ??= (a => a) : (a: number) => void +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function foo2 (f?: (a: number) => void) { +>foo2 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ||= (a => a) +>f ||= (a => a) : (a: number) => void +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function foo3 (f?: (a: number) => void) { +>foo3 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f &&= (a => a) +>f &&= (a => a) : ((a: number) => number) | undefined +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : ((a: number) => void) | undefined +>42 : 42 +} + +function bar1 (f?: (a: number) => void) { +>bar1 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ??= (f.toString(), (a => a)) +>f ??= (f.toString(), (a => a)) : (a: number) => void +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : any +>f.toString : any +>f : undefined +>toString : any +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function bar2 (f?: (a: number) => void) { +>bar2 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ||= (f.toString(), (a => a)) +>f ||= (f.toString(), (a => a)) : (a: number) => void +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : any +>f.toString : any +>f : undefined +>toString : any +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function bar3 (f?: (a: number) => void) { +>bar3 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f &&= (f.toString(), (a => a)) +>f &&= (f.toString(), (a => a)) : ((a: number) => number) | undefined +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : string +>f.toString : () => string +>f : (a: number) => void +>toString : () => string +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : ((a: number) => void) | undefined +>42 : 42 +} + diff --git a/tests/baselines/reference/logicalAssignment5(target=esnext).errors.txt b/tests/baselines/reference/logicalAssignment5(target=esnext).errors.txt new file mode 100644 index 0000000000000..8e9760990b033 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=esnext).errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(13,5): error TS2722: Cannot invoke an object which is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(17,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(22,12): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts(28,5): error TS2722: Cannot invoke an object which is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts (4 errors) ==== + function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) + } + + function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) + } + + function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) + ~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + } + + function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + ~ +!!! error TS2532: Object is possibly 'undefined'. + f(42) + } + + function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + ~ +!!! error TS2532: Object is possibly 'undefined'. + f(42) + } + + function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) + ~ +!!! error TS2722: Cannot invoke an object which is possibly 'undefined'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment5(target=esnext).js b/tests/baselines/reference/logicalAssignment5(target=esnext).js new file mode 100644 index 0000000000000..21d965459dc6f --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=esnext).js @@ -0,0 +1,58 @@ +//// [logicalAssignment5.ts] +function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) +} + +function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) +} + +function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) +} + +function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + f(42) +} + +function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + f(42) +} + +function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) +} + + +//// [logicalAssignment5.js] +"use strict"; +function foo1(f) { + f ??= (a => a); + f(42); +} +function foo2(f) { + f ||= (a => a); + f(42); +} +function foo3(f) { + f &&= (a => a); + f(42); +} +function bar1(f) { + f ??= (f.toString(), (a => a)); + f(42); +} +function bar2(f) { + f ||= (f.toString(), (a => a)); + f(42); +} +function bar3(f) { + f &&= (f.toString(), (a => a)); + f(42); +} diff --git a/tests/baselines/reference/logicalAssignment5(target=esnext).symbols b/tests/baselines/reference/logicalAssignment5(target=esnext).symbols new file mode 100644 index 0000000000000..5862d6b68d406 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=esnext).symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts === +function foo1 (f?: (a: number) => void) { +>foo1 : Symbol(foo1, Decl(logicalAssignment5.ts, 0, 0)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 0, 20)) + + f ??= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 1, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 1, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 0, 15)) +} + +function foo2 (f?: (a: number) => void) { +>foo2 : Symbol(foo2, Decl(logicalAssignment5.ts, 3, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 5, 20)) + + f ||= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 6, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 6, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 5, 15)) +} + +function foo3 (f?: (a: number) => void) { +>foo3 : Symbol(foo3, Decl(logicalAssignment5.ts, 8, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 10, 20)) + + f &&= (a => a) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 11, 11)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 11, 11)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 10, 15)) +} + +function bar1 (f?: (a: number) => void) { +>bar1 : Symbol(bar1, Decl(logicalAssignment5.ts, 13, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 15, 20)) + + f ??= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 16, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 16, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 15, 15)) +} + +function bar2 (f?: (a: number) => void) { +>bar2 : Symbol(bar2, Decl(logicalAssignment5.ts, 18, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 20, 20)) + + f ||= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 21, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 21, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 20, 15)) +} + +function bar3 (f?: (a: number) => void) { +>bar3 : Symbol(bar3, Decl(logicalAssignment5.ts, 23, 1)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 25, 20)) + + f &&= (f.toString(), (a => a)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>f.toString : Symbol(Function.toString, Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +>toString : Symbol(Function.toString, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 26, 26)) +>a : Symbol(a, Decl(logicalAssignment5.ts, 26, 26)) + + f(42) +>f : Symbol(f, Decl(logicalAssignment5.ts, 25, 15)) +} + diff --git a/tests/baselines/reference/logicalAssignment5(target=esnext).types b/tests/baselines/reference/logicalAssignment5(target=esnext).types new file mode 100644 index 0000000000000..6ffb9b65a123e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment5(target=esnext).types @@ -0,0 +1,133 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts === +function foo1 (f?: (a: number) => void) { +>foo1 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ??= (a => a) +>f ??= (a => a) : (a: number) => void +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function foo2 (f?: (a: number) => void) { +>foo2 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ||= (a => a) +>f ||= (a => a) : (a: number) => void +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function foo3 (f?: (a: number) => void) { +>foo3 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f &&= (a => a) +>f &&= (a => a) : ((a: number) => number) | undefined +>f : ((a: number) => void) | undefined +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : ((a: number) => void) | undefined +>42 : 42 +} + +function bar1 (f?: (a: number) => void) { +>bar1 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ??= (f.toString(), (a => a)) +>f ??= (f.toString(), (a => a)) : (a: number) => void +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : any +>f.toString : any +>f : undefined +>toString : any +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function bar2 (f?: (a: number) => void) { +>bar2 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f ||= (f.toString(), (a => a)) +>f ||= (f.toString(), (a => a)) : (a: number) => void +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : any +>f.toString : any +>f : undefined +>toString : any +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : (a: number) => void +>42 : 42 +} + +function bar3 (f?: (a: number) => void) { +>bar3 : (f?: ((a: number) => void) | undefined) => void +>f : ((a: number) => void) | undefined +>a : number + + f &&= (f.toString(), (a => a)) +>f &&= (f.toString(), (a => a)) : ((a: number) => number) | undefined +>f : ((a: number) => void) | undefined +>(f.toString(), (a => a)) : (a: number) => number +>f.toString(), (a => a) : (a: number) => number +>f.toString() : string +>f.toString : () => string +>f : (a: number) => void +>toString : () => string +>(a => a) : (a: number) => number +>a => a : (a: number) => number +>a : number +>a : number + + f(42) +>f(42) : void +>f : ((a: number) => void) | undefined +>42 : 42 +} + diff --git a/tests/baselines/reference/logicalAssignment6(target=es2015).errors.txt b/tests/baselines/reference/logicalAssignment6(target=es2015).errors.txt new file mode 100644 index 0000000000000..0af71a2ba4eaa --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2015).errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts (2 errors) ==== + function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); + } + + function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); + } + + function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment6(target=es2015).js b/tests/baselines/reference/logicalAssignment6(target=es2015).js new file mode 100644 index 0000000000000..5b002760a2ebc --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2015).js @@ -0,0 +1,24 @@ +//// [logicalAssignment6.ts] +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); +} + +//// [logicalAssignment6.js] +"use strict"; +function foo1(results, results1) { + (results || (results = results1 || (results1 = []))).push(100); +} +function foo2(results, results1) { + (results !== null && results !== void 0 ? results : (results = results1 !== null && results1 !== void 0 ? results1 : (results1 = []))).push(100); +} +function foo3(results, results1) { + (results && (results = results1 && (results1 = []))).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment6(target=es2015).symbols b/tests/baselines/reference/logicalAssignment6(target=es2015).symbols new file mode 100644 index 0000000000000..d91ebbaa4508d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2015).symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment6.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 0, 44)) + + (results ||= (results1 ||= [])).push(100); +>(results ||= (results1 ||= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 0, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment6.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 4, 44)) + + (results ??= (results1 ??= [])).push(100); +>(results ??= (results1 ??= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 4, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment6.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 8, 44)) + + (results &&= (results1 &&= [])).push(100); +>(results &&= (results1 &&= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 8, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment6(target=es2015).types b/tests/baselines/reference/logicalAssignment6(target=es2015).types new file mode 100644 index 0000000000000..3cf295045a6d9 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2015).types @@ -0,0 +1,57 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ||= (results1 ||= [])).push(100); +>(results ||= (results1 ||= [])).push(100) : number +>(results ||= (results1 ||= [])).push : (...items: number[]) => number +>(results ||= (results1 ||= [])) : number[] +>results ||= (results1 ||= []) : number[] +>results : number[] | undefined +>(results1 ||= []) : number[] +>results1 ||= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ??= (results1 ??= [])).push(100); +>(results ??= (results1 ??= [])).push(100) : number +>(results ??= (results1 ??= [])).push : (...items: number[]) => number +>(results ??= (results1 ??= [])) : number[] +>results ??= (results1 ??= []) : number[] +>results : number[] | undefined +>(results1 ??= []) : number[] +>results1 ??= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results &&= (results1 &&= [])).push(100); +>(results &&= (results1 &&= [])).push(100) : number +>(results &&= (results1 &&= [])).push : (...items: never[]) => number +>(results &&= (results1 &&= [])) : never[] | undefined +>results &&= (results1 &&= []) : never[] | undefined +>results : number[] | undefined +>(results1 &&= []) : never[] | undefined +>results1 &&= [] : never[] | undefined +>results1 : number[] | undefined +>[] : never[] +>push : (...items: never[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment6(target=es2020).errors.txt b/tests/baselines/reference/logicalAssignment6(target=es2020).errors.txt new file mode 100644 index 0000000000000..0af71a2ba4eaa --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2020).errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts (2 errors) ==== + function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); + } + + function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); + } + + function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment6(target=es2020).js b/tests/baselines/reference/logicalAssignment6(target=es2020).js new file mode 100644 index 0000000000000..4d8032ddb8e2e --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2020).js @@ -0,0 +1,24 @@ +//// [logicalAssignment6.ts] +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); +} + +//// [logicalAssignment6.js] +"use strict"; +function foo1(results, results1) { + (results || (results = results1 || (results1 = []))).push(100); +} +function foo2(results, results1) { + (results ?? (results = results1 ?? (results1 = []))).push(100); +} +function foo3(results, results1) { + (results && (results = results1 && (results1 = []))).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment6(target=es2020).symbols b/tests/baselines/reference/logicalAssignment6(target=es2020).symbols new file mode 100644 index 0000000000000..d91ebbaa4508d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2020).symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment6.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 0, 44)) + + (results ||= (results1 ||= [])).push(100); +>(results ||= (results1 ||= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 0, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment6.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 4, 44)) + + (results ??= (results1 ??= [])).push(100); +>(results ??= (results1 ??= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 4, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment6.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 8, 44)) + + (results &&= (results1 &&= [])).push(100); +>(results &&= (results1 &&= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 8, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment6(target=es2020).types b/tests/baselines/reference/logicalAssignment6(target=es2020).types new file mode 100644 index 0000000000000..3cf295045a6d9 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=es2020).types @@ -0,0 +1,57 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ||= (results1 ||= [])).push(100); +>(results ||= (results1 ||= [])).push(100) : number +>(results ||= (results1 ||= [])).push : (...items: number[]) => number +>(results ||= (results1 ||= [])) : number[] +>results ||= (results1 ||= []) : number[] +>results : number[] | undefined +>(results1 ||= []) : number[] +>results1 ||= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ??= (results1 ??= [])).push(100); +>(results ??= (results1 ??= [])).push(100) : number +>(results ??= (results1 ??= [])).push : (...items: number[]) => number +>(results ??= (results1 ??= [])) : number[] +>results ??= (results1 ??= []) : number[] +>results : number[] | undefined +>(results1 ??= []) : number[] +>results1 ??= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results &&= (results1 &&= [])).push(100); +>(results &&= (results1 &&= [])).push(100) : number +>(results &&= (results1 &&= [])).push : (...items: never[]) => number +>(results &&= (results1 &&= [])) : never[] | undefined +>results &&= (results1 &&= []) : never[] | undefined +>results : number[] | undefined +>(results1 &&= []) : never[] | undefined +>results1 &&= [] : never[] | undefined +>results1 : number[] | undefined +>[] : never[] +>push : (...items: never[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment6(target=esnext).errors.txt b/tests/baselines/reference/logicalAssignment6(target=esnext).errors.txt new file mode 100644 index 0000000000000..0af71a2ba4eaa --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=esnext).errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts(10,5): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts(10,42): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts (2 errors) ==== + function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); + } + + function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); + } + + function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment6(target=esnext).js b/tests/baselines/reference/logicalAssignment6(target=esnext).js new file mode 100644 index 0000000000000..9d209c9e30159 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=esnext).js @@ -0,0 +1,24 @@ +//// [logicalAssignment6.ts] +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); +} + +//// [logicalAssignment6.js] +"use strict"; +function foo1(results, results1) { + (results ||= (results1 ||= [])).push(100); +} +function foo2(results, results1) { + (results ??= (results1 ??= [])).push(100); +} +function foo3(results, results1) { + (results &&= (results1 &&= [])).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment6(target=esnext).symbols b/tests/baselines/reference/logicalAssignment6(target=esnext).symbols new file mode 100644 index 0000000000000..d91ebbaa4508d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=esnext).symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment6.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 0, 44)) + + (results ||= (results1 ||= [])).push(100); +>(results ||= (results1 ||= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 0, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment6.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 4, 44)) + + (results ??= (results1 ??= [])).push(100); +>(results ??= (results1 ??= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 4, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment6.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 8, 44)) + + (results &&= (results1 &&= [])).push(100); +>(results &&= (results1 &&= [])).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment6.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment6.ts, 8, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment6(target=esnext).types b/tests/baselines/reference/logicalAssignment6(target=esnext).types new file mode 100644 index 0000000000000..3cf295045a6d9 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment6(target=esnext).types @@ -0,0 +1,57 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ||= (results1 ||= [])).push(100); +>(results ||= (results1 ||= [])).push(100) : number +>(results ||= (results1 ||= [])).push : (...items: number[]) => number +>(results ||= (results1 ||= [])) : number[] +>results ||= (results1 ||= []) : number[] +>results : number[] | undefined +>(results1 ||= []) : number[] +>results1 ||= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ??= (results1 ??= [])).push(100); +>(results ??= (results1 ??= [])).push(100) : number +>(results ??= (results1 ??= [])).push : (...items: number[]) => number +>(results ??= (results1 ??= [])) : number[] +>results ??= (results1 ??= []) : number[] +>results : number[] | undefined +>(results1 ??= []) : number[] +>results1 ??= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results &&= (results1 &&= [])).push(100); +>(results &&= (results1 &&= [])).push(100) : number +>(results &&= (results1 &&= [])).push : (...items: never[]) => number +>(results &&= (results1 &&= [])) : never[] | undefined +>results &&= (results1 &&= []) : never[] | undefined +>results : number[] | undefined +>(results1 &&= []) : never[] | undefined +>results1 &&= [] : never[] | undefined +>results1 : number[] | undefined +>[] : never[] +>push : (...items: never[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment7(target=es2015).errors.txt b/tests/baselines/reference/logicalAssignment7(target=es2015).errors.txt new file mode 100644 index 0000000000000..c7f29aa3a33a1 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2015).errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts (2 errors) ==== + function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); + } + + function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); + } + + function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment7(target=es2015).js b/tests/baselines/reference/logicalAssignment7(target=es2015).js new file mode 100644 index 0000000000000..a0f67c80e53b3 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2015).js @@ -0,0 +1,24 @@ +//// [logicalAssignment7.ts] +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); +} + +//// [logicalAssignment7.js] +"use strict"; +function foo1(results, results1) { + (results || (results = results1 || (results1 = []))).push(100); +} +function foo2(results, results1) { + (results !== null && results !== void 0 ? results : (results = results1 !== null && results1 !== void 0 ? results1 : (results1 = []))).push(100); +} +function foo3(results, results1) { + (results && (results = results1 && (results1 = []))).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment7(target=es2015).symbols b/tests/baselines/reference/logicalAssignment7(target=es2015).symbols new file mode 100644 index 0000000000000..7bde5161df5a7 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2015).symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment7.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 0, 44)) + + (results ||= results1 ||= []).push(100); +>(results ||= results1 ||= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 0, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment7.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 4, 44)) + + (results ??= results1 ??= []).push(100); +>(results ??= results1 ??= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 4, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment7.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 8, 44)) + + (results &&= results1 &&= []).push(100); +>(results &&= results1 &&= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 8, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment7(target=es2015).types b/tests/baselines/reference/logicalAssignment7(target=es2015).types new file mode 100644 index 0000000000000..250fb4072f508 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2015).types @@ -0,0 +1,54 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ||= results1 ||= []).push(100); +>(results ||= results1 ||= []).push(100) : number +>(results ||= results1 ||= []).push : (...items: number[]) => number +>(results ||= results1 ||= []) : number[] +>results ||= results1 ||= [] : number[] +>results : number[] | undefined +>results1 ||= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ??= results1 ??= []).push(100); +>(results ??= results1 ??= []).push(100) : number +>(results ??= results1 ??= []).push : (...items: number[]) => number +>(results ??= results1 ??= []) : number[] +>results ??= results1 ??= [] : number[] +>results : number[] | undefined +>results1 ??= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results &&= results1 &&= []).push(100); +>(results &&= results1 &&= []).push(100) : number +>(results &&= results1 &&= []).push : (...items: never[]) => number +>(results &&= results1 &&= []) : never[] | undefined +>results &&= results1 &&= [] : never[] | undefined +>results : number[] | undefined +>results1 &&= [] : never[] | undefined +>results1 : number[] | undefined +>[] : never[] +>push : (...items: never[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment7(target=es2020).errors.txt b/tests/baselines/reference/logicalAssignment7(target=es2020).errors.txt new file mode 100644 index 0000000000000..c7f29aa3a33a1 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2020).errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts (2 errors) ==== + function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); + } + + function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); + } + + function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment7(target=es2020).js b/tests/baselines/reference/logicalAssignment7(target=es2020).js new file mode 100644 index 0000000000000..38a14a64191e4 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2020).js @@ -0,0 +1,24 @@ +//// [logicalAssignment7.ts] +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); +} + +//// [logicalAssignment7.js] +"use strict"; +function foo1(results, results1) { + (results || (results = results1 || (results1 = []))).push(100); +} +function foo2(results, results1) { + (results ?? (results = results1 ?? (results1 = []))).push(100); +} +function foo3(results, results1) { + (results && (results = results1 && (results1 = []))).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment7(target=es2020).symbols b/tests/baselines/reference/logicalAssignment7(target=es2020).symbols new file mode 100644 index 0000000000000..7bde5161df5a7 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2020).symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment7.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 0, 44)) + + (results ||= results1 ||= []).push(100); +>(results ||= results1 ||= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 0, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment7.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 4, 44)) + + (results ??= results1 ??= []).push(100); +>(results ??= results1 ??= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 4, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment7.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 8, 44)) + + (results &&= results1 &&= []).push(100); +>(results &&= results1 &&= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 8, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment7(target=es2020).types b/tests/baselines/reference/logicalAssignment7(target=es2020).types new file mode 100644 index 0000000000000..250fb4072f508 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=es2020).types @@ -0,0 +1,54 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ||= results1 ||= []).push(100); +>(results ||= results1 ||= []).push(100) : number +>(results ||= results1 ||= []).push : (...items: number[]) => number +>(results ||= results1 ||= []) : number[] +>results ||= results1 ||= [] : number[] +>results : number[] | undefined +>results1 ||= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ??= results1 ??= []).push(100); +>(results ??= results1 ??= []).push(100) : number +>(results ??= results1 ??= []).push : (...items: number[]) => number +>(results ??= results1 ??= []) : number[] +>results ??= results1 ??= [] : number[] +>results : number[] | undefined +>results1 ??= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results &&= results1 &&= []).push(100); +>(results &&= results1 &&= []).push(100) : number +>(results &&= results1 &&= []).push : (...items: never[]) => number +>(results &&= results1 &&= []) : never[] | undefined +>results &&= results1 &&= [] : never[] | undefined +>results : number[] | undefined +>results1 &&= [] : never[] | undefined +>results1 : number[] | undefined +>[] : never[] +>push : (...items: never[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment7(target=esnext).errors.txt b/tests/baselines/reference/logicalAssignment7(target=esnext).errors.txt new file mode 100644 index 0000000000000..c7f29aa3a33a1 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=esnext).errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts(10,5): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts(10,40): error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts (2 errors) ==== + function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); + } + + function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); + } + + function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type 'never'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment7(target=esnext).js b/tests/baselines/reference/logicalAssignment7(target=esnext).js new file mode 100644 index 0000000000000..1b83f24c7affd --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=esnext).js @@ -0,0 +1,24 @@ +//// [logicalAssignment7.ts] +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); +} + +//// [logicalAssignment7.js] +"use strict"; +function foo1(results, results1) { + (results ||= results1 ||= []).push(100); +} +function foo2(results, results1) { + (results ??= results1 ??= []).push(100); +} +function foo3(results, results1) { + (results &&= results1 &&= []).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment7(target=esnext).symbols b/tests/baselines/reference/logicalAssignment7(target=esnext).symbols new file mode 100644 index 0000000000000..7bde5161df5a7 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=esnext).symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment7.ts, 0, 0)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 0, 44)) + + (results ||= results1 ||= []).push(100); +>(results ||= results1 ||= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 0, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 0, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment7.ts, 2, 1)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 4, 44)) + + (results ??= results1 ??= []).push(100); +>(results ??= results1 ??= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 4, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 4, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment7.ts, 6, 1)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 8, 44)) + + (results &&= results1 &&= []).push(100); +>(results &&= results1 &&= []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment7.ts, 8, 14)) +>results1 : Symbol(results1, Decl(logicalAssignment7.ts, 8, 44)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment7(target=esnext).types b/tests/baselines/reference/logicalAssignment7(target=esnext).types new file mode 100644 index 0000000000000..250fb4072f508 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment7(target=esnext).types @@ -0,0 +1,54 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts === +function foo1(results: number[] | undefined, results1: number[] | undefined) { +>foo1 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ||= results1 ||= []).push(100); +>(results ||= results1 ||= []).push(100) : number +>(results ||= results1 ||= []).push : (...items: number[]) => number +>(results ||= results1 ||= []) : number[] +>results ||= results1 ||= [] : number[] +>results : number[] | undefined +>results1 ||= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { +>foo2 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results ??= results1 ??= []).push(100); +>(results ??= results1 ??= []).push(100) : number +>(results ??= results1 ??= []).push : (...items: number[]) => number +>(results ??= results1 ??= []) : number[] +>results ??= results1 ??= [] : number[] +>results : number[] | undefined +>results1 ??= [] : number[] +>results1 : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { +>foo3 : (results: number[] | undefined, results1: number[] | undefined) => void +>results : number[] | undefined +>results1 : number[] | undefined + + (results &&= results1 &&= []).push(100); +>(results &&= results1 &&= []).push(100) : number +>(results &&= results1 &&= []).push : (...items: never[]) => number +>(results &&= results1 &&= []) : never[] | undefined +>results &&= results1 &&= [] : never[] | undefined +>results : number[] | undefined +>results1 &&= [] : never[] | undefined +>results1 : number[] | undefined +>[] : never[] +>push : (...items: never[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment8(target=es2015).errors.txt b/tests/baselines/reference/logicalAssignment8(target=es2015).errors.txt new file mode 100644 index 0000000000000..82b49d50c3e51 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2015).errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts(12,5): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts (1 errors) ==== + declare const bar: { value?: number[] } | undefined + + function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); + } + + function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); + } + + function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment8(target=es2015).js b/tests/baselines/reference/logicalAssignment8(target=es2015).js new file mode 100644 index 0000000000000..3d32063651e40 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2015).js @@ -0,0 +1,29 @@ +//// [logicalAssignment8.ts] +declare const bar: { value?: number[] } | undefined + +function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); +} + +function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); +} + +//// [logicalAssignment8.js] +"use strict"; +function foo1(results) { + var _a; + (results || (results = (_a = bar === null || bar === void 0 ? void 0 : bar.value) !== null && _a !== void 0 ? _a : [])).push(100); +} +function foo2(results) { + var _a; + (results !== null && results !== void 0 ? results : (results = (_a = bar === null || bar === void 0 ? void 0 : bar.value) !== null && _a !== void 0 ? _a : [])).push(100); +} +function foo3(results) { + var _a; + (results && (results = (_a = bar === null || bar === void 0 ? void 0 : bar.value) !== null && _a !== void 0 ? _a : [])).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment8(target=es2015).symbols b/tests/baselines/reference/logicalAssignment8(target=es2015).symbols new file mode 100644 index 0000000000000..e92c95fa8915d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2015).symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts === +declare const bar: { value?: number[] } | undefined +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) + +function foo1(results: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment8.ts, 0, 51)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14)) + + (results ||= bar?.value ?? []).push(100); +>(results ||= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment8.ts, 4, 1)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14)) + + (results ??= bar?.value ?? []).push(100); +>(results ??= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment8.ts, 8, 1)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14)) + + (results &&= bar?.value ?? []).push(100); +>(results &&= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment8(target=es2015).types b/tests/baselines/reference/logicalAssignment8(target=es2015).types new file mode 100644 index 0000000000000..5c9de4aecdbcf --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2015).types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts === +declare const bar: { value?: number[] } | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined + +function foo1(results: number[] | undefined) { +>foo1 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ||= bar?.value ?? []).push(100); +>(results ||= bar?.value ?? []).push(100) : number +>(results ||= bar?.value ?? []).push : (...items: number[]) => number +>(results ||= bar?.value ?? []) : number[] +>results ||= bar?.value ?? [] : number[] +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined) { +>foo2 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ??= bar?.value ?? []).push(100); +>(results ??= bar?.value ?? []).push(100) : number +>(results ??= bar?.value ?? []).push : (...items: number[]) => number +>(results ??= bar?.value ?? []) : number[] +>results ??= bar?.value ?? [] : number[] +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined) { +>foo3 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results &&= bar?.value ?? []).push(100); +>(results &&= bar?.value ?? []).push(100) : number +>(results &&= bar?.value ?? []).push : (...items: number[]) => number +>(results &&= bar?.value ?? []) : number[] | undefined +>results &&= bar?.value ?? [] : number[] | undefined +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment8(target=es2020).errors.txt b/tests/baselines/reference/logicalAssignment8(target=es2020).errors.txt new file mode 100644 index 0000000000000..82b49d50c3e51 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2020).errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts(12,5): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts (1 errors) ==== + declare const bar: { value?: number[] } | undefined + + function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); + } + + function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); + } + + function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment8(target=es2020).js b/tests/baselines/reference/logicalAssignment8(target=es2020).js new file mode 100644 index 0000000000000..6d8a806979a7f --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2020).js @@ -0,0 +1,26 @@ +//// [logicalAssignment8.ts] +declare const bar: { value?: number[] } | undefined + +function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); +} + +function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); +} + +//// [logicalAssignment8.js] +"use strict"; +function foo1(results) { + (results || (results = bar?.value ?? [])).push(100); +} +function foo2(results) { + (results ?? (results = bar?.value ?? [])).push(100); +} +function foo3(results) { + (results && (results = bar?.value ?? [])).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment8(target=es2020).symbols b/tests/baselines/reference/logicalAssignment8(target=es2020).symbols new file mode 100644 index 0000000000000..e92c95fa8915d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2020).symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts === +declare const bar: { value?: number[] } | undefined +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) + +function foo1(results: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment8.ts, 0, 51)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14)) + + (results ||= bar?.value ?? []).push(100); +>(results ||= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment8.ts, 4, 1)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14)) + + (results ??= bar?.value ?? []).push(100); +>(results ??= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment8.ts, 8, 1)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14)) + + (results &&= bar?.value ?? []).push(100); +>(results &&= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment8(target=es2020).types b/tests/baselines/reference/logicalAssignment8(target=es2020).types new file mode 100644 index 0000000000000..5c9de4aecdbcf --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=es2020).types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts === +declare const bar: { value?: number[] } | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined + +function foo1(results: number[] | undefined) { +>foo1 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ||= bar?.value ?? []).push(100); +>(results ||= bar?.value ?? []).push(100) : number +>(results ||= bar?.value ?? []).push : (...items: number[]) => number +>(results ||= bar?.value ?? []) : number[] +>results ||= bar?.value ?? [] : number[] +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined) { +>foo2 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ??= bar?.value ?? []).push(100); +>(results ??= bar?.value ?? []).push(100) : number +>(results ??= bar?.value ?? []).push : (...items: number[]) => number +>(results ??= bar?.value ?? []) : number[] +>results ??= bar?.value ?? [] : number[] +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined) { +>foo3 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results &&= bar?.value ?? []).push(100); +>(results &&= bar?.value ?? []).push(100) : number +>(results &&= bar?.value ?? []).push : (...items: number[]) => number +>(results &&= bar?.value ?? []) : number[] | undefined +>results &&= bar?.value ?? [] : number[] | undefined +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/logicalAssignment8(target=esnext).errors.txt b/tests/baselines/reference/logicalAssignment8(target=esnext).errors.txt new file mode 100644 index 0000000000000..82b49d50c3e51 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=esnext).errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts(12,5): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts (1 errors) ==== + declare const bar: { value?: number[] } | undefined + + function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); + } + + function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); + } + + function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + } \ No newline at end of file diff --git a/tests/baselines/reference/logicalAssignment8(target=esnext).js b/tests/baselines/reference/logicalAssignment8(target=esnext).js new file mode 100644 index 0000000000000..64c9fa99337a6 --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=esnext).js @@ -0,0 +1,26 @@ +//// [logicalAssignment8.ts] +declare const bar: { value?: number[] } | undefined + +function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); +} + +function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); +} + +//// [logicalAssignment8.js] +"use strict"; +function foo1(results) { + (results ||= bar?.value ?? []).push(100); +} +function foo2(results) { + (results ??= bar?.value ?? []).push(100); +} +function foo3(results) { + (results &&= bar?.value ?? []).push(100); +} diff --git a/tests/baselines/reference/logicalAssignment8(target=esnext).symbols b/tests/baselines/reference/logicalAssignment8(target=esnext).symbols new file mode 100644 index 0000000000000..e92c95fa8915d --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=esnext).symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts === +declare const bar: { value?: number[] } | undefined +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) + +function foo1(results: number[] | undefined) { +>foo1 : Symbol(foo1, Decl(logicalAssignment8.ts, 0, 51)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14)) + + (results ||= bar?.value ?? []).push(100); +>(results ||= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo2(results: number[] | undefined) { +>foo2 : Symbol(foo2, Decl(logicalAssignment8.ts, 4, 1)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14)) + + (results ??= bar?.value ?? []).push(100); +>(results ??= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} + +function foo3(results: number[] | undefined) { +>foo3 : Symbol(foo3, Decl(logicalAssignment8.ts, 8, 1)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14)) + + (results &&= bar?.value ?? []).push(100); +>(results &&= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14)) +>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13)) +>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +} diff --git a/tests/baselines/reference/logicalAssignment8(target=esnext).types b/tests/baselines/reference/logicalAssignment8(target=esnext).types new file mode 100644 index 0000000000000..5c9de4aecdbcf --- /dev/null +++ b/tests/baselines/reference/logicalAssignment8(target=esnext).types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts === +declare const bar: { value?: number[] } | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined + +function foo1(results: number[] | undefined) { +>foo1 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ||= bar?.value ?? []).push(100); +>(results ||= bar?.value ?? []).push(100) : number +>(results ||= bar?.value ?? []).push : (...items: number[]) => number +>(results ||= bar?.value ?? []) : number[] +>results ||= bar?.value ?? [] : number[] +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo2(results: number[] | undefined) { +>foo2 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results ??= bar?.value ?? []).push(100); +>(results ??= bar?.value ?? []).push(100) : number +>(results ??= bar?.value ?? []).push : (...items: number[]) => number +>(results ??= bar?.value ?? []) : number[] +>results ??= bar?.value ?? [] : number[] +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} + +function foo3(results: number[] | undefined) { +>foo3 : (results: number[] | undefined) => void +>results : number[] | undefined + + (results &&= bar?.value ?? []).push(100); +>(results &&= bar?.value ?? []).push(100) : number +>(results &&= bar?.value ?? []).push : (...items: number[]) => number +>(results &&= bar?.value ?? []) : number[] | undefined +>results &&= bar?.value ?? [] : number[] | undefined +>results : number[] | undefined +>bar?.value ?? [] : number[] +>bar?.value : number[] | undefined +>bar : { value?: number[] | undefined; } | undefined +>value : number[] | undefined +>[] : never[] +>push : (...items: number[]) => number +>100 : 100 +} diff --git a/tests/baselines/reference/nullishCoalescingOperator1.js b/tests/baselines/reference/nullishCoalescingOperator1.js index c138222970cce..e02ce7490a40e 100644 --- a/tests/baselines/reference/nullishCoalescingOperator1.js +++ b/tests/baselines/reference/nullishCoalescingOperator1.js @@ -67,7 +67,6 @@ else { //// [nullishCoalescingOperator1.js] "use strict"; -var _a; var aa1 = a1 !== null && a1 !== void 0 ? a1 : 'whatever'; var aa2 = a2 !== null && a2 !== void 0 ? a2 : 'whatever'; var aa3 = a3 !== null && a3 !== void 0 ? a3 : 'whatever'; @@ -94,7 +93,7 @@ if (maybeBool !== null && maybeBool !== void 0 ? maybeBool : true) { else { foo(); } -if ((_a = false) !== null && _a !== void 0 ? _a : true) { +if (false !== null && false !== void 0 ? false : true) { foo(); } else { diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts new file mode 100644 index 0000000000000..cb1b51369e6d3 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment1.ts @@ -0,0 +1,27 @@ +// @strict: true +// @target: esnext, es2020, es2015 +declare let a: string | undefined +declare let b: string | undefined +declare let c: string | undefined + +declare let d: number | undefined +declare let e: number | undefined +declare let f: number | undefined + +declare let g: 0 | 1 | 42 +declare let h: 0 | 1 | 42 +declare let i: 0 | 1 | 42 + + +a &&= "foo" +b ||= "foo" +c ??= "foo" + + +d &&= 42 +e ||= 42 +f ??= 42 + +g &&= 42 +h ||= 42 +i ??= 42 diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts new file mode 100644 index 0000000000000..30bd5b9254df5 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment2.ts @@ -0,0 +1,29 @@ +// @strict: true +// @target: esnext, es2020, es2015 +interface A { + foo: { + bar(): { + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' + } + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A +declare const a: A +declare const b: A +declare const c: A + +a.baz &&= result.baz +b.baz ||= result.baz +c.baz ??= result.baz + +a.foo["baz"] &&= result.foo.baz +b.foo["baz"] ||= result.foo.baz +c.foo["baz"] ??= result.foo.baz + +a.foo.bar().baz &&= result.foo.bar().baz +b.foo.bar().baz ||= result.foo.bar().baz +c.foo.bar().baz ??= result.foo.bar().baz + diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts new file mode 100644 index 0000000000000..ea6085ece8023 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment3.ts @@ -0,0 +1,15 @@ +// @strict: true +// @target: esnext, es2020, es2015 +interface A { + baz: 0 | 1 | 42 | undefined | '' +} + +declare const result: A; +declare const a: A; +declare const b: A; +declare const c: A; + +(a.baz) &&= result.baz; +(b.baz) ||= result.baz; +(c.baz) ??= result.baz; + diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts new file mode 100644 index 0000000000000..bb13be7db6bb5 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts @@ -0,0 +1,52 @@ +// @strict: true +// @target: esnext, es2020, es2015 +// @allowUnreachableCode: false + +function foo1(results: number[] | undefined) { + (results ||= []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= []).push(100); +} + +function foo3(results: number[] | undefined) { + results ||= []; + results.push(100); +} + +function foo4(results: number[] | undefined) { + results ??= []; + results.push(100); +} + +interface ThingWithOriginal { + name: string; + original?: ThingWithOriginal +} +declare const v: number +function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) { + if (v === 1) { + if (thing &&= thing.original) { + thing.name; + } + } + else if (v === 2) { + if (thing &&= defaultValue) { + thing.name; + defaultValue.name + } + } + else if (v === 3) { + if (thing ||= defaultValue) { + thing.name; + defaultValue.name; + } + } + else { + if (thing ??= defaultValue) { + thing.name; + defaultValue.name; + } + } +} \ No newline at end of file diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts new file mode 100644 index 0000000000000..f9e4317b8ee84 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment5.ts @@ -0,0 +1,32 @@ +// @strict: true +// @target: esnext, es2020, es2015 + +function foo1 (f?: (a: number) => void) { + f ??= (a => a) + f(42) +} + +function foo2 (f?: (a: number) => void) { + f ||= (a => a) + f(42) +} + +function foo3 (f?: (a: number) => void) { + f &&= (a => a) + f(42) +} + +function bar1 (f?: (a: number) => void) { + f ??= (f.toString(), (a => a)) + f(42) +} + +function bar2 (f?: (a: number) => void) { + f ||= (f.toString(), (a => a)) + f(42) +} + +function bar3 (f?: (a: number) => void) { + f &&= (f.toString(), (a => a)) + f(42) +} diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts new file mode 100644 index 0000000000000..3fa7987f72081 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment6.ts @@ -0,0 +1,14 @@ +// @strict: true +// @target: esnext, es2020, es2015 + +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= (results1 ||= [])).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= (results1 ??= [])).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= (results1 &&= [])).push(100); +} \ No newline at end of file diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts new file mode 100644 index 0000000000000..78812fa0b73f6 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment7.ts @@ -0,0 +1,14 @@ +// @strict: true +// @target: esnext, es2020, es2015 + +function foo1(results: number[] | undefined, results1: number[] | undefined) { + (results ||= results1 ||= []).push(100); +} + +function foo2(results: number[] | undefined, results1: number[] | undefined) { + (results ??= results1 ??= []).push(100); +} + +function foo3(results: number[] | undefined, results1: number[] | undefined) { + (results &&= results1 &&= []).push(100); +} \ No newline at end of file diff --git a/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts new file mode 100644 index 0000000000000..15fe3b74b5e53 --- /dev/null +++ b/tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts @@ -0,0 +1,16 @@ +// @strict: true +// @target: esnext, es2020, es2015 + +declare const bar: { value?: number[] } | undefined + +function foo1(results: number[] | undefined) { + (results ||= bar?.value ?? []).push(100); +} + +function foo2(results: number[] | undefined) { + (results ??= bar?.value ?? []).push(100); +} + +function foo3(results: number[] | undefined) { + (results &&= bar?.value ?? []).push(100); +} \ No newline at end of file