diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 637910961922f..030ece62b21a8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1015,7 +1015,8 @@ namespace ts { else { return node.kind === SyntaxKind.BinaryExpression && ( (node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || - (node).operatorToken.kind === SyntaxKind.BarBarToken); + (node).operatorToken.kind === SyntaxKind.BarBarToken || + (node).operatorToken.kind === SyntaxKind.QuestionQuestionToken); } } } @@ -1466,7 +1467,7 @@ namespace ts { function bindBinaryExpressionFlow(node: BinaryExpression) { const operator = node.operatorToken.kind; - if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken) { + if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) { if (isTopLevelLogicalExpression(node)) { const postExpressionLabel = createBranchLabel(); bindLogicalExpression(node, postExpressionLabel, postExpressionLabel); @@ -2948,7 +2949,7 @@ namespace ts { init = init && getRightMostAssignedExpression(init); if (init) { const isPrototypeAssignment = isPrototypeAccess(isVariableDeclaration(node) ? node.name : isBinaryExpression(node) ? node.left : node); - return !!getExpandoInitializer(isBinaryExpression(init) && init.operatorToken.kind === SyntaxKind.BarBarToken ? init.right : init, isPrototypeAssignment); + return !!getExpandoInitializer(isBinaryExpression(init) && (init.operatorToken.kind === SyntaxKind.BarBarToken || init.operatorToken.kind === SyntaxKind.QuestionQuestionToken) ? init.right : init, isPrototypeAssignment); } return false; } @@ -3424,7 +3425,10 @@ namespace ts { const operatorTokenKind = node.operatorToken.kind; const leftKind = node.left.kind; - if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ObjectLiteralExpression) { + if (operatorTokenKind === SyntaxKind.QuestionQuestionToken) { + 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 transformFlags |= TransformFlags.AssertES2018 | TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0303668818bfd..14e64d0a8feb3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13254,7 +13254,7 @@ namespace ts { return isContextSensitive((node).whenTrue) || isContextSensitive((node).whenFalse); case SyntaxKind.BinaryExpression: - return (node).operatorToken.kind === SyntaxKind.BarBarToken && + return ((node).operatorToken.kind === SyntaxKind.BarBarToken || (node).operatorToken.kind === SyntaxKind.QuestionQuestionToken) && (isContextSensitive((node).left) || isContextSensitive((node).right)); case SyntaxKind.PropertyAssignment: return isContextSensitive((node).initializer); @@ -19697,7 +19697,8 @@ namespace ts { // will be a subtype or the same type as the argument. function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type { // for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a` - if (isOptionalChainRoot(expr.parent)) { + if (isOptionalChainRoot(expr.parent) || + isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === SyntaxKind.QuestionQuestionToken && expr.parent.left === expr) { return narrowTypeByOptionality(type, expr, assumeTrue); } switch (expr.kind) { @@ -20903,6 +20904,7 @@ namespace ts { } return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive; case SyntaxKind.BarBarToken: + case SyntaxKind.QuestionQuestionToken: // When an || expression has a contextual type, the operands are contextually typed by that type, except // when that type originates in a binding pattern, the right operand is contextually typed by the type of // the left operand. When an || expression has no contextual type, the right operand is contextually typed @@ -26467,16 +26469,29 @@ namespace ts { if (isInJSFile(node) && getAssignedExpandoInitializer(node)) { return checkExpression(node.right, checkMode); } + checkGrammarNullishCoalesceWithLogicalExpression(node); return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node); } + function checkGrammarNullishCoalesceWithLogicalExpression(node: BinaryExpression) { + const { left, operatorToken, right } = node; + if (operatorToken.kind === SyntaxKind.QuestionQuestionToken) { + if (isBinaryExpression(left) && (left.operatorToken.kind === SyntaxKind.BarBarToken || left.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken)) { + grammarErrorOnNode(left, Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, tokenToString(left.operatorToken.kind), tokenToString(operatorToken.kind)); + } + if (isBinaryExpression(right) && (right.operatorToken.kind === SyntaxKind.BarBarToken || right.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken)) { + grammarErrorOnNode(right, Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, tokenToString(right.operatorToken.kind), tokenToString(operatorToken.kind)); + } + } + } + function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, checkMode?: CheckMode, errorNode?: Node): Type { const operator = operatorToken.kind; if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) { return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === SyntaxKind.ThisKeyword); } let leftType: Type; - if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken) { + if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) { leftType = checkTruthinessExpression(left, checkMode); } else { @@ -26637,6 +26652,10 @@ namespace ts { return getTypeFacts(leftType) & TypeFacts.Falsy ? getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) : leftType; + case SyntaxKind.QuestionQuestionToken: + return getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ? + getUnionType([getNonNullableType(leftType), rightType], UnionReduction.Subtype) : + leftType; case SyntaxKind.EqualsToken: const declKind = isBinaryExpression(left.parent) ? getAssignmentDeclarationKind(left.parent) : AssignmentDeclarationKind.None; checkAssignmentDeclaration(declKind, rightType); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d04fff0f46c77..c5bde22eaba8f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3273,6 +3273,10 @@ "category": "Error", "code": 5075 }, + "'{0}' and '{1}' operations cannot be mixed without parentheses.": { + "category": "Error", + "code": 5076 + }, "Generates a sourcemap for each corresponding '.d.ts' file.": { "category": "Message", diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 7d32cc884fc43..321fee7e6a818 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3248,6 +3248,10 @@ namespace ts { return createBinary(left, SyntaxKind.BarBarToken, right); } + export function createNullishCoalesce(left: Expression, right: Expression) { + return createBinary(left, SyntaxKind.QuestionQuestionToken, right); + } + export function createLogicalNot(operand: Expression) { return createPrefix(SyntaxKind.ExclamationToken, operand); } @@ -4593,7 +4597,7 @@ namespace ts { const binaryOperatorPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, binaryOperator); const binaryOperatorAssociativity = getOperatorAssociativity(SyntaxKind.BinaryExpression, binaryOperator); const emittedOperand = skipPartiallyEmittedExpressions(operand); - if (!isLeftSideOfBinary && operand.kind === SyntaxKind.ArrowFunction && binaryOperatorPrecedence > 4) { + if (!isLeftSideOfBinary && operand.kind === SyntaxKind.ArrowFunction && binaryOperatorPrecedence > 3) { // We need to parenthesize arrow functions on the right side to avoid it being // parsed as parenthesized expression: `a && (() => {})` return true; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7a02e412fddae..fcf0353b1894f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3009,6 +3009,10 @@ namespace ts { return parseJSDocAllType(/*postfixEquals*/ false); case SyntaxKind.AsteriskEqualsToken: return parseJSDocAllType(/*postfixEquals*/ true); + case SyntaxKind.QuestionQuestionToken: + // If there is '??', consider that is prefix '?' in JSDoc type. + scanner.reScanQuestionToken(); + // falls through case SyntaxKind.QuestionToken: return parseJSDocUnknownOrNullableType(); case SyntaxKind.FunctionKeyword: @@ -4800,6 +4804,7 @@ namespace ts { case SyntaxKind.ExclamationEqualsEqualsToken: // foo !== case SyntaxKind.AmpersandAmpersandToken: // foo && case SyntaxKind.BarBarToken: // foo || + case SyntaxKind.QuestionQuestionToken: // foo ?? case SyntaxKind.CaretToken: // foo ^ case SyntaxKind.AmpersandToken: // foo & case SyntaxKind.BarToken: // foo | diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 18c96f94127d2..fbad8240bd353 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -33,6 +33,7 @@ namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): JsxTokenSyntaxKind; reScanLessThanToken(): SyntaxKind; + reScanQuestionToken(): SyntaxKind; scanJsxToken(): JsxTokenSyntaxKind; scanJsDocToken(): JSDocSyntaxKind; scan(): SyntaxKind; @@ -184,6 +185,7 @@ namespace ts { "&&": SyntaxKind.AmpersandAmpersandToken, "||": SyntaxKind.BarBarToken, "?": SyntaxKind.QuestionToken, + "??": SyntaxKind.QuestionQuestionToken, "?.": SyntaxKind.QuestionDotToken, ":": SyntaxKind.ColonToken, "=": SyntaxKind.EqualsToken, @@ -902,6 +904,7 @@ namespace ts { scanJsxAttributeValue, reScanJsxToken, reScanLessThanToken, + reScanQuestionToken, scanJsxToken, scanJsDocToken, scan, @@ -1834,6 +1837,10 @@ namespace ts { pos++; return token = SyntaxKind.QuestionDotToken; } + if (text.charCodeAt(pos) === CharacterCodes.question) { + pos++; + return token = SyntaxKind.QuestionQuestionToken; + } return token = SyntaxKind.QuestionToken; case CharacterCodes.openBracket: pos++; @@ -2023,6 +2030,12 @@ namespace ts { return token; } + function reScanQuestionToken(): SyntaxKind { + Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); + pos = tokenPos + 1; + return token = SyntaxKind.QuestionToken; + } + function scanJsxToken(): JsxTokenSyntaxKind { startPos = tokenPos = pos; diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts index c51ad4119d297..a138907e23670 100644 --- a/src/compiler/transformers/esnext.ts +++ b/src/compiler/transformers/esnext.ts @@ -2,7 +2,7 @@ namespace ts { export function transformESNext(context: TransformationContext) { const { - hoistVariableDeclaration + hoistVariableDeclaration, } = context; return chainBundle(transformSourceFile); @@ -28,7 +28,12 @@ namespace ts { Debug.assertNotNode(updated, isSyntheticReference); return updated; } - // falls through + return visitEachChild(node, visitor, context); + case SyntaxKind.BinaryExpression: + if ((node).operatorToken.kind === SyntaxKind.QuestionQuestionToken) { + return transformNullishCoalescingExpression(node); + } + return visitEachChild(node, visitor, context); default: return visitEachChild(node, visitor, context); } @@ -172,5 +177,39 @@ namespace ts { ); return thisArg ? createSyntheticReferenceExpression(target, thisArg) : target; } + + function createNotNullCondition(node: Expression) { + return createBinary( + createBinary( + node, + createToken(SyntaxKind.ExclamationEqualsEqualsToken), + createNull() + ), + createToken(SyntaxKind.AmpersandAmpersandToken), + createBinary( + node, + createToken(SyntaxKind.ExclamationEqualsEqualsToken), + createVoidZero() + ) + ); + } + + function transformNullishCoalescingExpression(node: BinaryExpression) { + const expressions: Expression[] = []; + let left = visitNode(node.left, visitor, isExpression); + if (!isIdentifier(left)) { + const temp = createTempVariable(hoistVariableDeclaration); + expressions.push(createAssignment(temp, left)); + left = temp; + } + expressions.push( + createParen( + createConditional( + createNotNullCondition(left), + left, + visitNode(node.right, visitor, isExpression))) + ); + return inlineExpressions(expressions); + } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d034b3544e646..62b8465f384ff 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -184,6 +184,7 @@ namespace ts { QuestionToken, ColonToken, AtToken, + QuestionQuestionToken, /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */ BacktickToken, // Assignments @@ -1566,7 +1567,8 @@ namespace ts { // see: https://tc39.github.io/ecma262/#prod-AssignmentExpression export type AssignmentOperatorOrHigher - = LogicalOperatorOrHigher + = SyntaxKind.QuestionQuestionToken + | LogicalOperatorOrHigher | AssignmentOperator ; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 63650297da274..8695cb4f39d3f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1861,22 +1861,26 @@ namespace ts { name = node.parent.name; decl = node.parent; } - else if (isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken && node.parent.right === node) { - name = node.parent.left; - decl = name; - } - else if (isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.BarBarToken) { - if (isVariableDeclaration(node.parent.parent) && node.parent.parent.initializer === node.parent) { - name = node.parent.parent.name; - decl = node.parent.parent; - } - else if (isBinaryExpression(node.parent.parent) && node.parent.parent.operatorToken.kind === SyntaxKind.EqualsToken && node.parent.parent.right === node.parent) { - name = node.parent.parent.left; + else if (isBinaryExpression(node.parent)) { + const parentNode = node.parent; + const parentNodeOperator = node.parent.operatorToken.kind; + if (parentNodeOperator === SyntaxKind.EqualsToken && parentNode.right === node) { + name = parentNode.left; decl = name; } + else if (parentNodeOperator === SyntaxKind.BarBarToken || parentNodeOperator === SyntaxKind.QuestionQuestionToken) { + if (isVariableDeclaration(parentNode.parent) && parentNode.parent.initializer === parentNode) { + name = parentNode.parent.name; + decl = parentNode.parent; + } + else if (isBinaryExpression(parentNode.parent) && parentNode.parent.operatorToken.kind === SyntaxKind.EqualsToken && parentNode.parent.right === parentNode) { + name = parentNode.parent.left; + decl = name; + } - if (!name || !isBindableStaticNameExpression(name) || !isSameEntityName(name, node.parent.left)) { - return undefined; + if (!name || !isBindableStaticNameExpression(name) || !isSameEntityName(name, parentNode.left)) { + return undefined; + } } } @@ -1893,7 +1897,8 @@ namespace ts { /** Get the initializer, taking into account defaulted Javascript initializers */ export function getEffectiveInitializer(node: HasExpressionInitializer) { if (isInJSFile(node) && node.initializer && - isBinaryExpression(node.initializer) && node.initializer.operatorToken.kind === SyntaxKind.BarBarToken && + isBinaryExpression(node.initializer) && + (node.initializer.operatorToken.kind === SyntaxKind.BarBarToken || node.initializer.operatorToken.kind === SyntaxKind.QuestionQuestionToken) && node.name && isEntityNameExpression(node.name) && isSameEntityName(node.name, node.initializer.left)) { return node.initializer.right; } @@ -1967,7 +1972,9 @@ namespace ts { * 'window.', 'global.' or 'self.' The second Lhs is otherwise ignored by the binder and checker. */ function getDefaultedExpandoInitializer(name: Expression, initializer: Expression, isPrototypeAssignment: boolean) { - const e = isBinaryExpression(initializer) && initializer.operatorToken.kind === SyntaxKind.BarBarToken && getExpandoInitializer(initializer.right, isPrototypeAssignment); + const e = isBinaryExpression(initializer) + && (initializer.operatorToken.kind === SyntaxKind.BarBarToken || initializer.operatorToken.kind === SyntaxKind.QuestionQuestionToken) + && getExpandoInitializer(initializer.right, isPrototypeAssignment); if (e && isSameEntityName(name, (initializer as BinaryExpression).left)) { return e; } @@ -1983,7 +1990,7 @@ namespace ts { /** Given an expando initializer, return its declaration name, or the left-hand side of the assignment if it's part of an assignment declaration. */ export function getNameOfExpando(node: Declaration): DeclarationName | undefined { if (isBinaryExpression(node.parent)) { - const parent = (node.parent.operatorToken.kind === SyntaxKind.BarBarToken && isBinaryExpression(node.parent.parent)) ? node.parent.parent : node.parent; + const parent = ((node.parent.operatorToken.kind === SyntaxKind.BarBarToken || node.parent.operatorToken.kind === SyntaxKind.QuestionQuestionToken) && isBinaryExpression(node.parent.parent)) ? node.parent.parent : node.parent; if (parent.operatorToken.kind === SyntaxKind.EqualsToken && isIdentifier(parent.left)) { return parent.left; } @@ -2296,7 +2303,7 @@ namespace ts { isBinaryExpression(node.expression) && getAssignmentDeclarationKind(node.expression) !== AssignmentDeclarationKind.None && isBinaryExpression(node.expression.right) && - node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken + (node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken || node.expression.right.operatorToken.kind === SyntaxKind.QuestionQuestionToken) ? node.expression.right.right : undefined; } @@ -3151,6 +3158,8 @@ namespace ts { export function getBinaryOperatorPrecedence(kind: SyntaxKind): number { switch (kind) { + case SyntaxKind.QuestionQuestionToken: + return 4; case SyntaxKind.BarBarToken: return 5; case SyntaxKind.AmpersandAmpersandToken: diff --git a/src/services/classifier.ts b/src/services/classifier.ts index 9e19755bc3692..a18f861db2dcf 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -391,6 +391,7 @@ namespace ts { case SyntaxKind.PercentEqualsToken: case SyntaxKind.EqualsToken: case SyntaxKind.CommaToken: + case SyntaxKind.QuestionQuestionToken: return true; default: return false; diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 555c913957361..11c3fbace614b 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -719,8 +719,9 @@ namespace ts.codefix { } break; - // LogicalOperator + // LogicalOperator Or NullishCoalescing case SyntaxKind.BarBarToken: + case SyntaxKind.QuestionQuestionToken: if (node === parent.left && (node.parent.parent.kind === SyntaxKind.VariableDeclaration || isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) { // var x = x || {}; diff --git a/src/testRunner/unittests/factory.ts b/src/testRunner/unittests/factory.ts index 5593b39256707..ae4258287fedb 100644 --- a/src/testRunner/unittests/factory.ts +++ b/src/testRunner/unittests/factory.ts @@ -75,6 +75,7 @@ namespace ts { checkRhs(SyntaxKind.PlusEqualsToken, /*expectParens*/ false); checkRhs(SyntaxKind.BarBarToken, /*expectParens*/ true); checkRhs(SyntaxKind.AmpersandAmpersandToken, /*expectParens*/ true); + checkRhs(SyntaxKind.QuestionQuestionToken, /*expectParens*/ true); checkRhs(SyntaxKind.EqualsEqualsToken, /*expectParens*/ true); }); }); diff --git a/src/testRunner/unittests/services/colorization.ts b/src/testRunner/unittests/services/colorization.ts index 0ee55d65eb031..1970fea7b0347 100644 --- a/src/testRunner/unittests/services/colorization.ts +++ b/src/testRunner/unittests/services/colorization.ts @@ -58,7 +58,7 @@ describe("unittests:: services:: Colorization", () => { describe("test getClassifications", () => { it("Returns correct token classes", () => { - testLexicalClassification("var x: string = \"foo\"; //Hello", + testLexicalClassification("var x: string = \"foo\" ?? \"bar\"; //Hello", ts.EndOfLineState.None, keyword("var"), whitespace(" "), @@ -67,6 +67,9 @@ describe("unittests:: services:: Colorization", () => { keyword("string"), operator("="), stringLiteral("\"foo\""), + whitespace(" "), + operator("??"), + stringLiteral("\"foo\""), comment("//Hello"), punctuation(";")); }); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3616e96d9d812..a14aeff22e1b6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -136,287 +136,288 @@ declare namespace ts { QuestionToken = 57, ColonToken = 58, AtToken = 59, + QuestionQuestionToken = 60, /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */ - BacktickToken = 60, - EqualsToken = 61, - PlusEqualsToken = 62, - MinusEqualsToken = 63, - AsteriskEqualsToken = 64, - AsteriskAsteriskEqualsToken = 65, - SlashEqualsToken = 66, - PercentEqualsToken = 67, - LessThanLessThanEqualsToken = 68, - GreaterThanGreaterThanEqualsToken = 69, - GreaterThanGreaterThanGreaterThanEqualsToken = 70, - AmpersandEqualsToken = 71, - BarEqualsToken = 72, - CaretEqualsToken = 73, - Identifier = 74, - BreakKeyword = 75, - CaseKeyword = 76, - CatchKeyword = 77, - ClassKeyword = 78, - ConstKeyword = 79, - ContinueKeyword = 80, - DebuggerKeyword = 81, - DefaultKeyword = 82, - DeleteKeyword = 83, - DoKeyword = 84, - ElseKeyword = 85, - EnumKeyword = 86, - ExportKeyword = 87, - ExtendsKeyword = 88, - FalseKeyword = 89, - FinallyKeyword = 90, - ForKeyword = 91, - FunctionKeyword = 92, - IfKeyword = 93, - ImportKeyword = 94, - InKeyword = 95, - InstanceOfKeyword = 96, - NewKeyword = 97, - NullKeyword = 98, - ReturnKeyword = 99, - SuperKeyword = 100, - SwitchKeyword = 101, - ThisKeyword = 102, - ThrowKeyword = 103, - TrueKeyword = 104, - TryKeyword = 105, - TypeOfKeyword = 106, - VarKeyword = 107, - VoidKeyword = 108, - WhileKeyword = 109, - WithKeyword = 110, - ImplementsKeyword = 111, - InterfaceKeyword = 112, - LetKeyword = 113, - PackageKeyword = 114, - PrivateKeyword = 115, - ProtectedKeyword = 116, - PublicKeyword = 117, - StaticKeyword = 118, - YieldKeyword = 119, - AbstractKeyword = 120, - AsKeyword = 121, - AssertsKeyword = 122, - AnyKeyword = 123, - AsyncKeyword = 124, - AwaitKeyword = 125, - BooleanKeyword = 126, - ConstructorKeyword = 127, - DeclareKeyword = 128, - GetKeyword = 129, - InferKeyword = 130, - IsKeyword = 131, - KeyOfKeyword = 132, - ModuleKeyword = 133, - NamespaceKeyword = 134, - NeverKeyword = 135, - ReadonlyKeyword = 136, - RequireKeyword = 137, - NumberKeyword = 138, - ObjectKeyword = 139, - SetKeyword = 140, - StringKeyword = 141, - SymbolKeyword = 142, - TypeKeyword = 143, - UndefinedKeyword = 144, - UniqueKeyword = 145, - UnknownKeyword = 146, - FromKeyword = 147, - GlobalKeyword = 148, - BigIntKeyword = 149, - OfKeyword = 150, - QualifiedName = 151, - ComputedPropertyName = 152, - TypeParameter = 153, - Parameter = 154, - Decorator = 155, - PropertySignature = 156, - PropertyDeclaration = 157, - MethodSignature = 158, - MethodDeclaration = 159, - Constructor = 160, - GetAccessor = 161, - SetAccessor = 162, - CallSignature = 163, - ConstructSignature = 164, - IndexSignature = 165, - TypePredicate = 166, - TypeReference = 167, - FunctionType = 168, - ConstructorType = 169, - TypeQuery = 170, - TypeLiteral = 171, - ArrayType = 172, - TupleType = 173, - OptionalType = 174, - RestType = 175, - UnionType = 176, - IntersectionType = 177, - ConditionalType = 178, - InferType = 179, - ParenthesizedType = 180, - ThisType = 181, - TypeOperator = 182, - IndexedAccessType = 183, - MappedType = 184, - LiteralType = 185, - ImportType = 186, - ObjectBindingPattern = 187, - ArrayBindingPattern = 188, - BindingElement = 189, - ArrayLiteralExpression = 190, - ObjectLiteralExpression = 191, - PropertyAccessExpression = 192, - ElementAccessExpression = 193, - CallExpression = 194, - NewExpression = 195, - TaggedTemplateExpression = 196, - TypeAssertionExpression = 197, - ParenthesizedExpression = 198, - FunctionExpression = 199, - ArrowFunction = 200, - DeleteExpression = 201, - TypeOfExpression = 202, - VoidExpression = 203, - AwaitExpression = 204, - PrefixUnaryExpression = 205, - PostfixUnaryExpression = 206, - BinaryExpression = 207, - ConditionalExpression = 208, - TemplateExpression = 209, - YieldExpression = 210, - SpreadElement = 211, - ClassExpression = 212, - OmittedExpression = 213, - ExpressionWithTypeArguments = 214, - AsExpression = 215, - NonNullExpression = 216, - MetaProperty = 217, - SyntheticExpression = 218, - TemplateSpan = 219, - SemicolonClassElement = 220, - Block = 221, - EmptyStatement = 222, - VariableStatement = 223, - ExpressionStatement = 224, - IfStatement = 225, - DoStatement = 226, - WhileStatement = 227, - ForStatement = 228, - ForInStatement = 229, - ForOfStatement = 230, - ContinueStatement = 231, - BreakStatement = 232, - ReturnStatement = 233, - WithStatement = 234, - SwitchStatement = 235, - LabeledStatement = 236, - ThrowStatement = 237, - TryStatement = 238, - DebuggerStatement = 239, - VariableDeclaration = 240, - VariableDeclarationList = 241, - FunctionDeclaration = 242, - ClassDeclaration = 243, - InterfaceDeclaration = 244, - TypeAliasDeclaration = 245, - EnumDeclaration = 246, - ModuleDeclaration = 247, - ModuleBlock = 248, - CaseBlock = 249, - NamespaceExportDeclaration = 250, - ImportEqualsDeclaration = 251, - ImportDeclaration = 252, - ImportClause = 253, - NamespaceImport = 254, - NamedImports = 255, - ImportSpecifier = 256, - ExportAssignment = 257, - ExportDeclaration = 258, - NamedExports = 259, - ExportSpecifier = 260, - MissingDeclaration = 261, - ExternalModuleReference = 262, - JsxElement = 263, - JsxSelfClosingElement = 264, - JsxOpeningElement = 265, - JsxClosingElement = 266, - JsxFragment = 267, - JsxOpeningFragment = 268, - JsxClosingFragment = 269, - JsxAttribute = 270, - JsxAttributes = 271, - JsxSpreadAttribute = 272, - JsxExpression = 273, - CaseClause = 274, - DefaultClause = 275, - HeritageClause = 276, - CatchClause = 277, - PropertyAssignment = 278, - ShorthandPropertyAssignment = 279, - SpreadAssignment = 280, - EnumMember = 281, - UnparsedPrologue = 282, - UnparsedPrepend = 283, - UnparsedText = 284, - UnparsedInternalText = 285, - UnparsedSyntheticReference = 286, - SourceFile = 287, - Bundle = 288, - UnparsedSource = 289, - InputFiles = 290, - JSDocTypeExpression = 291, - JSDocAllType = 292, - JSDocUnknownType = 293, - JSDocNullableType = 294, - JSDocNonNullableType = 295, - JSDocOptionalType = 296, - JSDocFunctionType = 297, - JSDocVariadicType = 298, - JSDocNamepathType = 299, - JSDocComment = 300, - JSDocTypeLiteral = 301, - JSDocSignature = 302, - JSDocTag = 303, - JSDocAugmentsTag = 304, - JSDocAuthorTag = 305, - JSDocClassTag = 306, - JSDocCallbackTag = 307, - JSDocEnumTag = 308, - JSDocParameterTag = 309, - JSDocReturnTag = 310, - JSDocThisTag = 311, - JSDocTypeTag = 312, - JSDocTemplateTag = 313, - JSDocTypedefTag = 314, - JSDocPropertyTag = 315, - SyntaxList = 316, - NotEmittedStatement = 317, - PartiallyEmittedExpression = 318, - CommaListExpression = 319, - MergeDeclarationMarker = 320, - EndOfDeclarationMarker = 321, - SyntheticReferenceExpression = 322, - Count = 323, - FirstAssignment = 61, - LastAssignment = 73, - FirstCompoundAssignment = 62, - LastCompoundAssignment = 73, - FirstReservedWord = 75, - LastReservedWord = 110, - FirstKeyword = 75, - LastKeyword = 150, - FirstFutureReservedWord = 111, - LastFutureReservedWord = 119, - FirstTypeNode = 166, - LastTypeNode = 186, + BacktickToken = 61, + EqualsToken = 62, + PlusEqualsToken = 63, + MinusEqualsToken = 64, + AsteriskEqualsToken = 65, + AsteriskAsteriskEqualsToken = 66, + SlashEqualsToken = 67, + PercentEqualsToken = 68, + LessThanLessThanEqualsToken = 69, + GreaterThanGreaterThanEqualsToken = 70, + GreaterThanGreaterThanGreaterThanEqualsToken = 71, + AmpersandEqualsToken = 72, + BarEqualsToken = 73, + CaretEqualsToken = 74, + Identifier = 75, + BreakKeyword = 76, + CaseKeyword = 77, + CatchKeyword = 78, + ClassKeyword = 79, + ConstKeyword = 80, + ContinueKeyword = 81, + DebuggerKeyword = 82, + DefaultKeyword = 83, + DeleteKeyword = 84, + DoKeyword = 85, + ElseKeyword = 86, + EnumKeyword = 87, + ExportKeyword = 88, + ExtendsKeyword = 89, + FalseKeyword = 90, + FinallyKeyword = 91, + ForKeyword = 92, + FunctionKeyword = 93, + IfKeyword = 94, + ImportKeyword = 95, + InKeyword = 96, + InstanceOfKeyword = 97, + NewKeyword = 98, + NullKeyword = 99, + ReturnKeyword = 100, + SuperKeyword = 101, + SwitchKeyword = 102, + ThisKeyword = 103, + ThrowKeyword = 104, + TrueKeyword = 105, + TryKeyword = 106, + TypeOfKeyword = 107, + VarKeyword = 108, + VoidKeyword = 109, + WhileKeyword = 110, + WithKeyword = 111, + ImplementsKeyword = 112, + InterfaceKeyword = 113, + LetKeyword = 114, + PackageKeyword = 115, + PrivateKeyword = 116, + ProtectedKeyword = 117, + PublicKeyword = 118, + StaticKeyword = 119, + YieldKeyword = 120, + AbstractKeyword = 121, + AsKeyword = 122, + AssertsKeyword = 123, + AnyKeyword = 124, + AsyncKeyword = 125, + AwaitKeyword = 126, + BooleanKeyword = 127, + ConstructorKeyword = 128, + DeclareKeyword = 129, + GetKeyword = 130, + InferKeyword = 131, + IsKeyword = 132, + KeyOfKeyword = 133, + ModuleKeyword = 134, + NamespaceKeyword = 135, + NeverKeyword = 136, + ReadonlyKeyword = 137, + RequireKeyword = 138, + NumberKeyword = 139, + ObjectKeyword = 140, + SetKeyword = 141, + StringKeyword = 142, + SymbolKeyword = 143, + TypeKeyword = 144, + UndefinedKeyword = 145, + UniqueKeyword = 146, + UnknownKeyword = 147, + FromKeyword = 148, + GlobalKeyword = 149, + BigIntKeyword = 150, + OfKeyword = 151, + QualifiedName = 152, + ComputedPropertyName = 153, + TypeParameter = 154, + Parameter = 155, + Decorator = 156, + PropertySignature = 157, + PropertyDeclaration = 158, + MethodSignature = 159, + MethodDeclaration = 160, + Constructor = 161, + GetAccessor = 162, + SetAccessor = 163, + CallSignature = 164, + ConstructSignature = 165, + IndexSignature = 166, + TypePredicate = 167, + TypeReference = 168, + FunctionType = 169, + ConstructorType = 170, + TypeQuery = 171, + TypeLiteral = 172, + ArrayType = 173, + TupleType = 174, + OptionalType = 175, + RestType = 176, + UnionType = 177, + IntersectionType = 178, + ConditionalType = 179, + InferType = 180, + ParenthesizedType = 181, + ThisType = 182, + TypeOperator = 183, + IndexedAccessType = 184, + MappedType = 185, + LiteralType = 186, + ImportType = 187, + ObjectBindingPattern = 188, + ArrayBindingPattern = 189, + BindingElement = 190, + ArrayLiteralExpression = 191, + ObjectLiteralExpression = 192, + PropertyAccessExpression = 193, + ElementAccessExpression = 194, + CallExpression = 195, + NewExpression = 196, + TaggedTemplateExpression = 197, + TypeAssertionExpression = 198, + ParenthesizedExpression = 199, + FunctionExpression = 200, + ArrowFunction = 201, + DeleteExpression = 202, + TypeOfExpression = 203, + VoidExpression = 204, + AwaitExpression = 205, + PrefixUnaryExpression = 206, + PostfixUnaryExpression = 207, + BinaryExpression = 208, + ConditionalExpression = 209, + TemplateExpression = 210, + YieldExpression = 211, + SpreadElement = 212, + ClassExpression = 213, + OmittedExpression = 214, + ExpressionWithTypeArguments = 215, + AsExpression = 216, + NonNullExpression = 217, + MetaProperty = 218, + SyntheticExpression = 219, + TemplateSpan = 220, + SemicolonClassElement = 221, + Block = 222, + EmptyStatement = 223, + VariableStatement = 224, + ExpressionStatement = 225, + IfStatement = 226, + DoStatement = 227, + WhileStatement = 228, + ForStatement = 229, + ForInStatement = 230, + ForOfStatement = 231, + ContinueStatement = 232, + BreakStatement = 233, + ReturnStatement = 234, + WithStatement = 235, + SwitchStatement = 236, + LabeledStatement = 237, + ThrowStatement = 238, + TryStatement = 239, + DebuggerStatement = 240, + VariableDeclaration = 241, + VariableDeclarationList = 242, + FunctionDeclaration = 243, + ClassDeclaration = 244, + InterfaceDeclaration = 245, + TypeAliasDeclaration = 246, + EnumDeclaration = 247, + ModuleDeclaration = 248, + ModuleBlock = 249, + CaseBlock = 250, + NamespaceExportDeclaration = 251, + ImportEqualsDeclaration = 252, + ImportDeclaration = 253, + ImportClause = 254, + NamespaceImport = 255, + NamedImports = 256, + ImportSpecifier = 257, + ExportAssignment = 258, + ExportDeclaration = 259, + NamedExports = 260, + ExportSpecifier = 261, + MissingDeclaration = 262, + ExternalModuleReference = 263, + JsxElement = 264, + JsxSelfClosingElement = 265, + JsxOpeningElement = 266, + JsxClosingElement = 267, + JsxFragment = 268, + JsxOpeningFragment = 269, + JsxClosingFragment = 270, + JsxAttribute = 271, + JsxAttributes = 272, + JsxSpreadAttribute = 273, + JsxExpression = 274, + CaseClause = 275, + DefaultClause = 276, + HeritageClause = 277, + CatchClause = 278, + PropertyAssignment = 279, + ShorthandPropertyAssignment = 280, + SpreadAssignment = 281, + EnumMember = 282, + UnparsedPrologue = 283, + UnparsedPrepend = 284, + UnparsedText = 285, + UnparsedInternalText = 286, + UnparsedSyntheticReference = 287, + SourceFile = 288, + Bundle = 289, + UnparsedSource = 290, + InputFiles = 291, + JSDocTypeExpression = 292, + JSDocAllType = 293, + JSDocUnknownType = 294, + JSDocNullableType = 295, + JSDocNonNullableType = 296, + JSDocOptionalType = 297, + JSDocFunctionType = 298, + JSDocVariadicType = 299, + JSDocNamepathType = 300, + JSDocComment = 301, + JSDocTypeLiteral = 302, + JSDocSignature = 303, + JSDocTag = 304, + JSDocAugmentsTag = 305, + JSDocAuthorTag = 306, + JSDocClassTag = 307, + JSDocCallbackTag = 308, + JSDocEnumTag = 309, + JSDocParameterTag = 310, + JSDocReturnTag = 311, + JSDocThisTag = 312, + JSDocTypeTag = 313, + JSDocTemplateTag = 314, + JSDocTypedefTag = 315, + JSDocPropertyTag = 316, + SyntaxList = 317, + NotEmittedStatement = 318, + PartiallyEmittedExpression = 319, + CommaListExpression = 320, + MergeDeclarationMarker = 321, + EndOfDeclarationMarker = 322, + SyntheticReferenceExpression = 323, + Count = 324, + FirstAssignment = 62, + LastAssignment = 74, + FirstCompoundAssignment = 63, + LastCompoundAssignment = 74, + FirstReservedWord = 76, + LastReservedWord = 111, + FirstKeyword = 76, + LastKeyword = 151, + FirstFutureReservedWord = 112, + LastFutureReservedWord = 120, + FirstTypeNode = 167, + LastTypeNode = 187, FirstPunctuation = 18, - LastPunctuation = 73, + LastPunctuation = 74, FirstToken = 0, - LastToken = 150, + LastToken = 151, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -424,14 +425,14 @@ declare namespace ts { FirstTemplateToken = 14, LastTemplateToken = 17, FirstBinaryOperator = 29, - LastBinaryOperator = 73, - FirstStatement = 223, - LastStatement = 239, - FirstNode = 151, - FirstJSDocNode = 291, - LastJSDocNode = 315, - FirstJSDocTagNode = 303, - LastJSDocTagNode = 315, + LastBinaryOperator = 74, + FirstStatement = 224, + LastStatement = 240, + FirstNode = 152, + FirstJSDocNode = 292, + LastJSDocNode = 316, + FirstJSDocTagNode = 304, + LastJSDocTagNode = 316, } export enum NodeFlags { None = 0, @@ -953,7 +954,7 @@ declare namespace ts { 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 AssignmentOperator = SyntaxKind.EqualsToken | CompoundAssignmentOperator; - export type AssignmentOperatorOrHigher = LogicalOperatorOrHigher | AssignmentOperator; + export type AssignmentOperatorOrHigher = SyntaxKind.QuestionQuestionToken | LogicalOperatorOrHigher | AssignmentOperator; export type BinaryOperator = AssignmentOperatorOrHigher | SyntaxKind.CommaToken; export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { @@ -3262,6 +3263,7 @@ declare namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): JsxTokenSyntaxKind; reScanLessThanToken(): SyntaxKind; + reScanQuestionToken(): SyntaxKind; scanJsxToken(): JsxTokenSyntaxKind; scanJsDocToken(): JSDocSyntaxKind; scan(): SyntaxKind; @@ -4200,6 +4202,7 @@ declare namespace ts { function createPostfixIncrement(operand: Expression): PostfixUnaryExpression; function createLogicalAnd(left: Expression, right: Expression): BinaryExpression; function createLogicalOr(left: Expression, right: Expression): BinaryExpression; + function createNullishCoalesce(left: Expression, right: Expression): BinaryExpression; function createLogicalNot(operand: Expression): PrefixUnaryExpression; function createVoidZero(): VoidExpression; function createExportDefault(expression: Expression): ExportAssignment; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8027692181810..062a4ba524fa1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -136,287 +136,288 @@ declare namespace ts { QuestionToken = 57, ColonToken = 58, AtToken = 59, + QuestionQuestionToken = 60, /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */ - BacktickToken = 60, - EqualsToken = 61, - PlusEqualsToken = 62, - MinusEqualsToken = 63, - AsteriskEqualsToken = 64, - AsteriskAsteriskEqualsToken = 65, - SlashEqualsToken = 66, - PercentEqualsToken = 67, - LessThanLessThanEqualsToken = 68, - GreaterThanGreaterThanEqualsToken = 69, - GreaterThanGreaterThanGreaterThanEqualsToken = 70, - AmpersandEqualsToken = 71, - BarEqualsToken = 72, - CaretEqualsToken = 73, - Identifier = 74, - BreakKeyword = 75, - CaseKeyword = 76, - CatchKeyword = 77, - ClassKeyword = 78, - ConstKeyword = 79, - ContinueKeyword = 80, - DebuggerKeyword = 81, - DefaultKeyword = 82, - DeleteKeyword = 83, - DoKeyword = 84, - ElseKeyword = 85, - EnumKeyword = 86, - ExportKeyword = 87, - ExtendsKeyword = 88, - FalseKeyword = 89, - FinallyKeyword = 90, - ForKeyword = 91, - FunctionKeyword = 92, - IfKeyword = 93, - ImportKeyword = 94, - InKeyword = 95, - InstanceOfKeyword = 96, - NewKeyword = 97, - NullKeyword = 98, - ReturnKeyword = 99, - SuperKeyword = 100, - SwitchKeyword = 101, - ThisKeyword = 102, - ThrowKeyword = 103, - TrueKeyword = 104, - TryKeyword = 105, - TypeOfKeyword = 106, - VarKeyword = 107, - VoidKeyword = 108, - WhileKeyword = 109, - WithKeyword = 110, - ImplementsKeyword = 111, - InterfaceKeyword = 112, - LetKeyword = 113, - PackageKeyword = 114, - PrivateKeyword = 115, - ProtectedKeyword = 116, - PublicKeyword = 117, - StaticKeyword = 118, - YieldKeyword = 119, - AbstractKeyword = 120, - AsKeyword = 121, - AssertsKeyword = 122, - AnyKeyword = 123, - AsyncKeyword = 124, - AwaitKeyword = 125, - BooleanKeyword = 126, - ConstructorKeyword = 127, - DeclareKeyword = 128, - GetKeyword = 129, - InferKeyword = 130, - IsKeyword = 131, - KeyOfKeyword = 132, - ModuleKeyword = 133, - NamespaceKeyword = 134, - NeverKeyword = 135, - ReadonlyKeyword = 136, - RequireKeyword = 137, - NumberKeyword = 138, - ObjectKeyword = 139, - SetKeyword = 140, - StringKeyword = 141, - SymbolKeyword = 142, - TypeKeyword = 143, - UndefinedKeyword = 144, - UniqueKeyword = 145, - UnknownKeyword = 146, - FromKeyword = 147, - GlobalKeyword = 148, - BigIntKeyword = 149, - OfKeyword = 150, - QualifiedName = 151, - ComputedPropertyName = 152, - TypeParameter = 153, - Parameter = 154, - Decorator = 155, - PropertySignature = 156, - PropertyDeclaration = 157, - MethodSignature = 158, - MethodDeclaration = 159, - Constructor = 160, - GetAccessor = 161, - SetAccessor = 162, - CallSignature = 163, - ConstructSignature = 164, - IndexSignature = 165, - TypePredicate = 166, - TypeReference = 167, - FunctionType = 168, - ConstructorType = 169, - TypeQuery = 170, - TypeLiteral = 171, - ArrayType = 172, - TupleType = 173, - OptionalType = 174, - RestType = 175, - UnionType = 176, - IntersectionType = 177, - ConditionalType = 178, - InferType = 179, - ParenthesizedType = 180, - ThisType = 181, - TypeOperator = 182, - IndexedAccessType = 183, - MappedType = 184, - LiteralType = 185, - ImportType = 186, - ObjectBindingPattern = 187, - ArrayBindingPattern = 188, - BindingElement = 189, - ArrayLiteralExpression = 190, - ObjectLiteralExpression = 191, - PropertyAccessExpression = 192, - ElementAccessExpression = 193, - CallExpression = 194, - NewExpression = 195, - TaggedTemplateExpression = 196, - TypeAssertionExpression = 197, - ParenthesizedExpression = 198, - FunctionExpression = 199, - ArrowFunction = 200, - DeleteExpression = 201, - TypeOfExpression = 202, - VoidExpression = 203, - AwaitExpression = 204, - PrefixUnaryExpression = 205, - PostfixUnaryExpression = 206, - BinaryExpression = 207, - ConditionalExpression = 208, - TemplateExpression = 209, - YieldExpression = 210, - SpreadElement = 211, - ClassExpression = 212, - OmittedExpression = 213, - ExpressionWithTypeArguments = 214, - AsExpression = 215, - NonNullExpression = 216, - MetaProperty = 217, - SyntheticExpression = 218, - TemplateSpan = 219, - SemicolonClassElement = 220, - Block = 221, - EmptyStatement = 222, - VariableStatement = 223, - ExpressionStatement = 224, - IfStatement = 225, - DoStatement = 226, - WhileStatement = 227, - ForStatement = 228, - ForInStatement = 229, - ForOfStatement = 230, - ContinueStatement = 231, - BreakStatement = 232, - ReturnStatement = 233, - WithStatement = 234, - SwitchStatement = 235, - LabeledStatement = 236, - ThrowStatement = 237, - TryStatement = 238, - DebuggerStatement = 239, - VariableDeclaration = 240, - VariableDeclarationList = 241, - FunctionDeclaration = 242, - ClassDeclaration = 243, - InterfaceDeclaration = 244, - TypeAliasDeclaration = 245, - EnumDeclaration = 246, - ModuleDeclaration = 247, - ModuleBlock = 248, - CaseBlock = 249, - NamespaceExportDeclaration = 250, - ImportEqualsDeclaration = 251, - ImportDeclaration = 252, - ImportClause = 253, - NamespaceImport = 254, - NamedImports = 255, - ImportSpecifier = 256, - ExportAssignment = 257, - ExportDeclaration = 258, - NamedExports = 259, - ExportSpecifier = 260, - MissingDeclaration = 261, - ExternalModuleReference = 262, - JsxElement = 263, - JsxSelfClosingElement = 264, - JsxOpeningElement = 265, - JsxClosingElement = 266, - JsxFragment = 267, - JsxOpeningFragment = 268, - JsxClosingFragment = 269, - JsxAttribute = 270, - JsxAttributes = 271, - JsxSpreadAttribute = 272, - JsxExpression = 273, - CaseClause = 274, - DefaultClause = 275, - HeritageClause = 276, - CatchClause = 277, - PropertyAssignment = 278, - ShorthandPropertyAssignment = 279, - SpreadAssignment = 280, - EnumMember = 281, - UnparsedPrologue = 282, - UnparsedPrepend = 283, - UnparsedText = 284, - UnparsedInternalText = 285, - UnparsedSyntheticReference = 286, - SourceFile = 287, - Bundle = 288, - UnparsedSource = 289, - InputFiles = 290, - JSDocTypeExpression = 291, - JSDocAllType = 292, - JSDocUnknownType = 293, - JSDocNullableType = 294, - JSDocNonNullableType = 295, - JSDocOptionalType = 296, - JSDocFunctionType = 297, - JSDocVariadicType = 298, - JSDocNamepathType = 299, - JSDocComment = 300, - JSDocTypeLiteral = 301, - JSDocSignature = 302, - JSDocTag = 303, - JSDocAugmentsTag = 304, - JSDocAuthorTag = 305, - JSDocClassTag = 306, - JSDocCallbackTag = 307, - JSDocEnumTag = 308, - JSDocParameterTag = 309, - JSDocReturnTag = 310, - JSDocThisTag = 311, - JSDocTypeTag = 312, - JSDocTemplateTag = 313, - JSDocTypedefTag = 314, - JSDocPropertyTag = 315, - SyntaxList = 316, - NotEmittedStatement = 317, - PartiallyEmittedExpression = 318, - CommaListExpression = 319, - MergeDeclarationMarker = 320, - EndOfDeclarationMarker = 321, - SyntheticReferenceExpression = 322, - Count = 323, - FirstAssignment = 61, - LastAssignment = 73, - FirstCompoundAssignment = 62, - LastCompoundAssignment = 73, - FirstReservedWord = 75, - LastReservedWord = 110, - FirstKeyword = 75, - LastKeyword = 150, - FirstFutureReservedWord = 111, - LastFutureReservedWord = 119, - FirstTypeNode = 166, - LastTypeNode = 186, + BacktickToken = 61, + EqualsToken = 62, + PlusEqualsToken = 63, + MinusEqualsToken = 64, + AsteriskEqualsToken = 65, + AsteriskAsteriskEqualsToken = 66, + SlashEqualsToken = 67, + PercentEqualsToken = 68, + LessThanLessThanEqualsToken = 69, + GreaterThanGreaterThanEqualsToken = 70, + GreaterThanGreaterThanGreaterThanEqualsToken = 71, + AmpersandEqualsToken = 72, + BarEqualsToken = 73, + CaretEqualsToken = 74, + Identifier = 75, + BreakKeyword = 76, + CaseKeyword = 77, + CatchKeyword = 78, + ClassKeyword = 79, + ConstKeyword = 80, + ContinueKeyword = 81, + DebuggerKeyword = 82, + DefaultKeyword = 83, + DeleteKeyword = 84, + DoKeyword = 85, + ElseKeyword = 86, + EnumKeyword = 87, + ExportKeyword = 88, + ExtendsKeyword = 89, + FalseKeyword = 90, + FinallyKeyword = 91, + ForKeyword = 92, + FunctionKeyword = 93, + IfKeyword = 94, + ImportKeyword = 95, + InKeyword = 96, + InstanceOfKeyword = 97, + NewKeyword = 98, + NullKeyword = 99, + ReturnKeyword = 100, + SuperKeyword = 101, + SwitchKeyword = 102, + ThisKeyword = 103, + ThrowKeyword = 104, + TrueKeyword = 105, + TryKeyword = 106, + TypeOfKeyword = 107, + VarKeyword = 108, + VoidKeyword = 109, + WhileKeyword = 110, + WithKeyword = 111, + ImplementsKeyword = 112, + InterfaceKeyword = 113, + LetKeyword = 114, + PackageKeyword = 115, + PrivateKeyword = 116, + ProtectedKeyword = 117, + PublicKeyword = 118, + StaticKeyword = 119, + YieldKeyword = 120, + AbstractKeyword = 121, + AsKeyword = 122, + AssertsKeyword = 123, + AnyKeyword = 124, + AsyncKeyword = 125, + AwaitKeyword = 126, + BooleanKeyword = 127, + ConstructorKeyword = 128, + DeclareKeyword = 129, + GetKeyword = 130, + InferKeyword = 131, + IsKeyword = 132, + KeyOfKeyword = 133, + ModuleKeyword = 134, + NamespaceKeyword = 135, + NeverKeyword = 136, + ReadonlyKeyword = 137, + RequireKeyword = 138, + NumberKeyword = 139, + ObjectKeyword = 140, + SetKeyword = 141, + StringKeyword = 142, + SymbolKeyword = 143, + TypeKeyword = 144, + UndefinedKeyword = 145, + UniqueKeyword = 146, + UnknownKeyword = 147, + FromKeyword = 148, + GlobalKeyword = 149, + BigIntKeyword = 150, + OfKeyword = 151, + QualifiedName = 152, + ComputedPropertyName = 153, + TypeParameter = 154, + Parameter = 155, + Decorator = 156, + PropertySignature = 157, + PropertyDeclaration = 158, + MethodSignature = 159, + MethodDeclaration = 160, + Constructor = 161, + GetAccessor = 162, + SetAccessor = 163, + CallSignature = 164, + ConstructSignature = 165, + IndexSignature = 166, + TypePredicate = 167, + TypeReference = 168, + FunctionType = 169, + ConstructorType = 170, + TypeQuery = 171, + TypeLiteral = 172, + ArrayType = 173, + TupleType = 174, + OptionalType = 175, + RestType = 176, + UnionType = 177, + IntersectionType = 178, + ConditionalType = 179, + InferType = 180, + ParenthesizedType = 181, + ThisType = 182, + TypeOperator = 183, + IndexedAccessType = 184, + MappedType = 185, + LiteralType = 186, + ImportType = 187, + ObjectBindingPattern = 188, + ArrayBindingPattern = 189, + BindingElement = 190, + ArrayLiteralExpression = 191, + ObjectLiteralExpression = 192, + PropertyAccessExpression = 193, + ElementAccessExpression = 194, + CallExpression = 195, + NewExpression = 196, + TaggedTemplateExpression = 197, + TypeAssertionExpression = 198, + ParenthesizedExpression = 199, + FunctionExpression = 200, + ArrowFunction = 201, + DeleteExpression = 202, + TypeOfExpression = 203, + VoidExpression = 204, + AwaitExpression = 205, + PrefixUnaryExpression = 206, + PostfixUnaryExpression = 207, + BinaryExpression = 208, + ConditionalExpression = 209, + TemplateExpression = 210, + YieldExpression = 211, + SpreadElement = 212, + ClassExpression = 213, + OmittedExpression = 214, + ExpressionWithTypeArguments = 215, + AsExpression = 216, + NonNullExpression = 217, + MetaProperty = 218, + SyntheticExpression = 219, + TemplateSpan = 220, + SemicolonClassElement = 221, + Block = 222, + EmptyStatement = 223, + VariableStatement = 224, + ExpressionStatement = 225, + IfStatement = 226, + DoStatement = 227, + WhileStatement = 228, + ForStatement = 229, + ForInStatement = 230, + ForOfStatement = 231, + ContinueStatement = 232, + BreakStatement = 233, + ReturnStatement = 234, + WithStatement = 235, + SwitchStatement = 236, + LabeledStatement = 237, + ThrowStatement = 238, + TryStatement = 239, + DebuggerStatement = 240, + VariableDeclaration = 241, + VariableDeclarationList = 242, + FunctionDeclaration = 243, + ClassDeclaration = 244, + InterfaceDeclaration = 245, + TypeAliasDeclaration = 246, + EnumDeclaration = 247, + ModuleDeclaration = 248, + ModuleBlock = 249, + CaseBlock = 250, + NamespaceExportDeclaration = 251, + ImportEqualsDeclaration = 252, + ImportDeclaration = 253, + ImportClause = 254, + NamespaceImport = 255, + NamedImports = 256, + ImportSpecifier = 257, + ExportAssignment = 258, + ExportDeclaration = 259, + NamedExports = 260, + ExportSpecifier = 261, + MissingDeclaration = 262, + ExternalModuleReference = 263, + JsxElement = 264, + JsxSelfClosingElement = 265, + JsxOpeningElement = 266, + JsxClosingElement = 267, + JsxFragment = 268, + JsxOpeningFragment = 269, + JsxClosingFragment = 270, + JsxAttribute = 271, + JsxAttributes = 272, + JsxSpreadAttribute = 273, + JsxExpression = 274, + CaseClause = 275, + DefaultClause = 276, + HeritageClause = 277, + CatchClause = 278, + PropertyAssignment = 279, + ShorthandPropertyAssignment = 280, + SpreadAssignment = 281, + EnumMember = 282, + UnparsedPrologue = 283, + UnparsedPrepend = 284, + UnparsedText = 285, + UnparsedInternalText = 286, + UnparsedSyntheticReference = 287, + SourceFile = 288, + Bundle = 289, + UnparsedSource = 290, + InputFiles = 291, + JSDocTypeExpression = 292, + JSDocAllType = 293, + JSDocUnknownType = 294, + JSDocNullableType = 295, + JSDocNonNullableType = 296, + JSDocOptionalType = 297, + JSDocFunctionType = 298, + JSDocVariadicType = 299, + JSDocNamepathType = 300, + JSDocComment = 301, + JSDocTypeLiteral = 302, + JSDocSignature = 303, + JSDocTag = 304, + JSDocAugmentsTag = 305, + JSDocAuthorTag = 306, + JSDocClassTag = 307, + JSDocCallbackTag = 308, + JSDocEnumTag = 309, + JSDocParameterTag = 310, + JSDocReturnTag = 311, + JSDocThisTag = 312, + JSDocTypeTag = 313, + JSDocTemplateTag = 314, + JSDocTypedefTag = 315, + JSDocPropertyTag = 316, + SyntaxList = 317, + NotEmittedStatement = 318, + PartiallyEmittedExpression = 319, + CommaListExpression = 320, + MergeDeclarationMarker = 321, + EndOfDeclarationMarker = 322, + SyntheticReferenceExpression = 323, + Count = 324, + FirstAssignment = 62, + LastAssignment = 74, + FirstCompoundAssignment = 63, + LastCompoundAssignment = 74, + FirstReservedWord = 76, + LastReservedWord = 111, + FirstKeyword = 76, + LastKeyword = 151, + FirstFutureReservedWord = 112, + LastFutureReservedWord = 120, + FirstTypeNode = 167, + LastTypeNode = 187, FirstPunctuation = 18, - LastPunctuation = 73, + LastPunctuation = 74, FirstToken = 0, - LastToken = 150, + LastToken = 151, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -424,14 +425,14 @@ declare namespace ts { FirstTemplateToken = 14, LastTemplateToken = 17, FirstBinaryOperator = 29, - LastBinaryOperator = 73, - FirstStatement = 223, - LastStatement = 239, - FirstNode = 151, - FirstJSDocNode = 291, - LastJSDocNode = 315, - FirstJSDocTagNode = 303, - LastJSDocTagNode = 315, + LastBinaryOperator = 74, + FirstStatement = 224, + LastStatement = 240, + FirstNode = 152, + FirstJSDocNode = 292, + LastJSDocNode = 316, + FirstJSDocTagNode = 304, + LastJSDocTagNode = 316, } export enum NodeFlags { None = 0, @@ -953,7 +954,7 @@ declare namespace ts { 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 AssignmentOperator = SyntaxKind.EqualsToken | CompoundAssignmentOperator; - export type AssignmentOperatorOrHigher = LogicalOperatorOrHigher | AssignmentOperator; + export type AssignmentOperatorOrHigher = SyntaxKind.QuestionQuestionToken | LogicalOperatorOrHigher | AssignmentOperator; export type BinaryOperator = AssignmentOperatorOrHigher | SyntaxKind.CommaToken; export type BinaryOperatorToken = Token; export interface BinaryExpression extends Expression, Declaration { @@ -3262,6 +3263,7 @@ declare namespace ts { scanJsxAttributeValue(): SyntaxKind; reScanJsxToken(): JsxTokenSyntaxKind; reScanLessThanToken(): SyntaxKind; + reScanQuestionToken(): SyntaxKind; scanJsxToken(): JsxTokenSyntaxKind; scanJsDocToken(): JSDocSyntaxKind; scan(): SyntaxKind; @@ -4200,6 +4202,7 @@ declare namespace ts { function createPostfixIncrement(operand: Expression): PostfixUnaryExpression; function createLogicalAnd(left: Expression, right: Expression): BinaryExpression; function createLogicalOr(left: Expression, right: Expression): BinaryExpression; + function createNullishCoalesce(left: Expression, right: Expression): BinaryExpression; function createLogicalNot(operand: Expression): PrefixUnaryExpression; function createVoidZero(): VoidExpression; function createExportDefault(expression: Expression): ExportAssignment; diff --git a/tests/baselines/reference/controlFlowNullishCoalesce.errors.txt b/tests/baselines/reference/controlFlowNullishCoalesce.errors.txt new file mode 100644 index 0000000000000..1e32f86a46019 --- /dev/null +++ b/tests/baselines/reference/controlFlowNullishCoalesce.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts(4,1): error TS2454: Variable 'a' is used before being assigned. + + +==== tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts (1 errors) ==== + // assignments in shortcutting rhs + let a: number; + o ?? (a = 1); + a.toString(); + ~ +!!! error TS2454: Variable 'a' is used before being assigned. + + // assignment flow + declare const o: { x: number } | undefined; + let x: { x: number } | boolean; + if (x = o ?? true) { + x; + } + + \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowNullishCoalesce.js b/tests/baselines/reference/controlFlowNullishCoalesce.js new file mode 100644 index 0000000000000..f49414771d3aa --- /dev/null +++ b/tests/baselines/reference/controlFlowNullishCoalesce.js @@ -0,0 +1,25 @@ +//// [controlFlowNullishCoalesce.ts] +// assignments in shortcutting rhs +let a: number; +o ?? (a = 1); +a.toString(); + +// assignment flow +declare const o: { x: number } | undefined; +let x: { x: number } | boolean; +if (x = o ?? true) { + x; +} + + + +//// [controlFlowNullishCoalesce.js] +"use strict"; +// assignments in shortcutting rhs +var a; +(o !== null && o !== void 0 ? o : (a = 1)); +a.toString(); +var x; +if (x = (o !== null && o !== void 0 ? o : true)) { + x; +} diff --git a/tests/baselines/reference/controlFlowNullishCoalesce.symbols b/tests/baselines/reference/controlFlowNullishCoalesce.symbols new file mode 100644 index 0000000000000..6b8f58db20b34 --- /dev/null +++ b/tests/baselines/reference/controlFlowNullishCoalesce.symbols @@ -0,0 +1,32 @@ +=== tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts === +// assignments in shortcutting rhs +let a: number; +>a : Symbol(a, Decl(controlFlowNullishCoalesce.ts, 1, 3)) + +o ?? (a = 1); +>o : Symbol(o, Decl(controlFlowNullishCoalesce.ts, 6, 13)) +>a : Symbol(a, Decl(controlFlowNullishCoalesce.ts, 1, 3)) + +a.toString(); +>a.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(controlFlowNullishCoalesce.ts, 1, 3)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + +// assignment flow +declare const o: { x: number } | undefined; +>o : Symbol(o, Decl(controlFlowNullishCoalesce.ts, 6, 13)) +>x : Symbol(x, Decl(controlFlowNullishCoalesce.ts, 6, 18)) + +let x: { x: number } | boolean; +>x : Symbol(x, Decl(controlFlowNullishCoalesce.ts, 7, 3)) +>x : Symbol(x, Decl(controlFlowNullishCoalesce.ts, 7, 8)) + +if (x = o ?? true) { +>x : Symbol(x, Decl(controlFlowNullishCoalesce.ts, 7, 3)) +>o : Symbol(o, Decl(controlFlowNullishCoalesce.ts, 6, 13)) + + x; +>x : Symbol(x, Decl(controlFlowNullishCoalesce.ts, 7, 3)) +} + + diff --git a/tests/baselines/reference/controlFlowNullishCoalesce.types b/tests/baselines/reference/controlFlowNullishCoalesce.types new file mode 100644 index 0000000000000..f94bbfd3baf3f --- /dev/null +++ b/tests/baselines/reference/controlFlowNullishCoalesce.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts === +// assignments in shortcutting rhs +let a: number; +>a : number + +o ?? (a = 1); +>o ?? (a = 1) : { x: number; } | 1 +>o : { x: number; } | undefined +>(a = 1) : 1 +>a = 1 : 1 +>a : number +>1 : 1 + +a.toString(); +>a.toString() : string +>a.toString : (radix?: number | undefined) => string +>a : number +>toString : (radix?: number | undefined) => string + +// assignment flow +declare const o: { x: number } | undefined; +>o : { x: number; } | undefined +>x : number + +let x: { x: number } | boolean; +>x : boolean | { x: number; } +>x : number + +if (x = o ?? true) { +>x = o ?? true : true | { x: number; } +>x : boolean | { x: number; } +>o ?? true : true | { x: number; } +>o : { x: number; } | undefined +>true : true + + x; +>x : true | { x: number; } +} + + diff --git a/tests/baselines/reference/nullishCoalescingOperator1.js b/tests/baselines/reference/nullishCoalescingOperator1.js new file mode 100644 index 0000000000000..87a149c1855aa --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator1.js @@ -0,0 +1,60 @@ +//// [nullishCoalescingOperator1.ts] +declare const a1: string | undefined | null +declare const a2: string | undefined | null +declare const a3: string | undefined | null +declare const a4: string | undefined | null + +declare const b1: number | undefined | null +declare const b2: number | undefined | null +declare const b3: number | undefined | null +declare const b4: number | undefined | null + +declare const c1: boolean | undefined | null +declare const c2: boolean | undefined | null +declare const c3: boolean | undefined | null +declare const c4: boolean | undefined | null + +interface I { a: string } +declare const d1: I | undefined | null +declare const d2: I | undefined | null +declare const d3: I | undefined | null +declare const d4: I | undefined | null + +const aa1 = a1 ?? 'whatever'; +const aa2 = a2 ?? 'whatever'; +const aa3 = a3 ?? 'whatever'; +const aa4 = a4 ?? 'whatever'; + +const bb1 = b1 ?? 1; +const bb2 = b2 ?? 1; +const bb3 = b3 ?? 1; +const bb4 = b4 ?? 1; + +const cc1 = c1 ?? true; +const cc2 = c2 ?? true; +const cc3 = c3 ?? true; +const cc4 = c4 ?? true; + +const dd1 = d1 ?? {b: 1}; +const dd2 = d2 ?? {b: 1}; +const dd3 = d3 ?? {b: 1}; +const dd4 = d4 ?? {b: 1}; + +//// [nullishCoalescingOperator1.js] +"use strict"; +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'); +var aa4 = (a4 !== null && a4 !== void 0 ? a4 : 'whatever'); +var bb1 = (b1 !== null && b1 !== void 0 ? b1 : 1); +var bb2 = (b2 !== null && b2 !== void 0 ? b2 : 1); +var bb3 = (b3 !== null && b3 !== void 0 ? b3 : 1); +var bb4 = (b4 !== null && b4 !== void 0 ? b4 : 1); +var cc1 = (c1 !== null && c1 !== void 0 ? c1 : true); +var cc2 = (c2 !== null && c2 !== void 0 ? c2 : true); +var cc3 = (c3 !== null && c3 !== void 0 ? c3 : true); +var cc4 = (c4 !== null && c4 !== void 0 ? c4 : true); +var dd1 = (d1 !== null && d1 !== void 0 ? d1 : { b: 1 }); +var dd2 = (d2 !== null && d2 !== void 0 ? d2 : { b: 1 }); +var dd3 = (d3 !== null && d3 !== void 0 ? d3 : { b: 1 }); +var dd4 = (d4 !== null && d4 !== void 0 ? d4 : { b: 1 }); diff --git a/tests/baselines/reference/nullishCoalescingOperator1.symbols b/tests/baselines/reference/nullishCoalescingOperator1.symbols new file mode 100644 index 0000000000000..fb95dee5096a6 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator1.symbols @@ -0,0 +1,125 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator1.ts === +declare const a1: string | undefined | null +>a1 : Symbol(a1, Decl(nullishCoalescingOperator1.ts, 0, 13)) + +declare const a2: string | undefined | null +>a2 : Symbol(a2, Decl(nullishCoalescingOperator1.ts, 1, 13)) + +declare const a3: string | undefined | null +>a3 : Symbol(a3, Decl(nullishCoalescingOperator1.ts, 2, 13)) + +declare const a4: string | undefined | null +>a4 : Symbol(a4, Decl(nullishCoalescingOperator1.ts, 3, 13)) + +declare const b1: number | undefined | null +>b1 : Symbol(b1, Decl(nullishCoalescingOperator1.ts, 5, 13)) + +declare const b2: number | undefined | null +>b2 : Symbol(b2, Decl(nullishCoalescingOperator1.ts, 6, 13)) + +declare const b3: number | undefined | null +>b3 : Symbol(b3, Decl(nullishCoalescingOperator1.ts, 7, 13)) + +declare const b4: number | undefined | null +>b4 : Symbol(b4, Decl(nullishCoalescingOperator1.ts, 8, 13)) + +declare const c1: boolean | undefined | null +>c1 : Symbol(c1, Decl(nullishCoalescingOperator1.ts, 10, 13)) + +declare const c2: boolean | undefined | null +>c2 : Symbol(c2, Decl(nullishCoalescingOperator1.ts, 11, 13)) + +declare const c3: boolean | undefined | null +>c3 : Symbol(c3, Decl(nullishCoalescingOperator1.ts, 12, 13)) + +declare const c4: boolean | undefined | null +>c4 : Symbol(c4, Decl(nullishCoalescingOperator1.ts, 13, 13)) + +interface I { a: string } +>I : Symbol(I, Decl(nullishCoalescingOperator1.ts, 13, 44)) +>a : Symbol(I.a, Decl(nullishCoalescingOperator1.ts, 15, 13)) + +declare const d1: I | undefined | null +>d1 : Symbol(d1, Decl(nullishCoalescingOperator1.ts, 16, 13)) +>I : Symbol(I, Decl(nullishCoalescingOperator1.ts, 13, 44)) + +declare const d2: I | undefined | null +>d2 : Symbol(d2, Decl(nullishCoalescingOperator1.ts, 17, 13)) +>I : Symbol(I, Decl(nullishCoalescingOperator1.ts, 13, 44)) + +declare const d3: I | undefined | null +>d3 : Symbol(d3, Decl(nullishCoalescingOperator1.ts, 18, 13)) +>I : Symbol(I, Decl(nullishCoalescingOperator1.ts, 13, 44)) + +declare const d4: I | undefined | null +>d4 : Symbol(d4, Decl(nullishCoalescingOperator1.ts, 19, 13)) +>I : Symbol(I, Decl(nullishCoalescingOperator1.ts, 13, 44)) + +const aa1 = a1 ?? 'whatever'; +>aa1 : Symbol(aa1, Decl(nullishCoalescingOperator1.ts, 21, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator1.ts, 0, 13)) + +const aa2 = a2 ?? 'whatever'; +>aa2 : Symbol(aa2, Decl(nullishCoalescingOperator1.ts, 22, 5)) +>a2 : Symbol(a2, Decl(nullishCoalescingOperator1.ts, 1, 13)) + +const aa3 = a3 ?? 'whatever'; +>aa3 : Symbol(aa3, Decl(nullishCoalescingOperator1.ts, 23, 5)) +>a3 : Symbol(a3, Decl(nullishCoalescingOperator1.ts, 2, 13)) + +const aa4 = a4 ?? 'whatever'; +>aa4 : Symbol(aa4, Decl(nullishCoalescingOperator1.ts, 24, 5)) +>a4 : Symbol(a4, Decl(nullishCoalescingOperator1.ts, 3, 13)) + +const bb1 = b1 ?? 1; +>bb1 : Symbol(bb1, Decl(nullishCoalescingOperator1.ts, 26, 5)) +>b1 : Symbol(b1, Decl(nullishCoalescingOperator1.ts, 5, 13)) + +const bb2 = b2 ?? 1; +>bb2 : Symbol(bb2, Decl(nullishCoalescingOperator1.ts, 27, 5)) +>b2 : Symbol(b2, Decl(nullishCoalescingOperator1.ts, 6, 13)) + +const bb3 = b3 ?? 1; +>bb3 : Symbol(bb3, Decl(nullishCoalescingOperator1.ts, 28, 5)) +>b3 : Symbol(b3, Decl(nullishCoalescingOperator1.ts, 7, 13)) + +const bb4 = b4 ?? 1; +>bb4 : Symbol(bb4, Decl(nullishCoalescingOperator1.ts, 29, 5)) +>b4 : Symbol(b4, Decl(nullishCoalescingOperator1.ts, 8, 13)) + +const cc1 = c1 ?? true; +>cc1 : Symbol(cc1, Decl(nullishCoalescingOperator1.ts, 31, 5)) +>c1 : Symbol(c1, Decl(nullishCoalescingOperator1.ts, 10, 13)) + +const cc2 = c2 ?? true; +>cc2 : Symbol(cc2, Decl(nullishCoalescingOperator1.ts, 32, 5)) +>c2 : Symbol(c2, Decl(nullishCoalescingOperator1.ts, 11, 13)) + +const cc3 = c3 ?? true; +>cc3 : Symbol(cc3, Decl(nullishCoalescingOperator1.ts, 33, 5)) +>c3 : Symbol(c3, Decl(nullishCoalescingOperator1.ts, 12, 13)) + +const cc4 = c4 ?? true; +>cc4 : Symbol(cc4, Decl(nullishCoalescingOperator1.ts, 34, 5)) +>c4 : Symbol(c4, Decl(nullishCoalescingOperator1.ts, 13, 13)) + +const dd1 = d1 ?? {b: 1}; +>dd1 : Symbol(dd1, Decl(nullishCoalescingOperator1.ts, 36, 5)) +>d1 : Symbol(d1, Decl(nullishCoalescingOperator1.ts, 16, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator1.ts, 36, 19)) + +const dd2 = d2 ?? {b: 1}; +>dd2 : Symbol(dd2, Decl(nullishCoalescingOperator1.ts, 37, 5)) +>d2 : Symbol(d2, Decl(nullishCoalescingOperator1.ts, 17, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator1.ts, 37, 19)) + +const dd3 = d3 ?? {b: 1}; +>dd3 : Symbol(dd3, Decl(nullishCoalescingOperator1.ts, 38, 5)) +>d3 : Symbol(d3, Decl(nullishCoalescingOperator1.ts, 18, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator1.ts, 38, 19)) + +const dd4 = d4 ?? {b: 1}; +>dd4 : Symbol(dd4, Decl(nullishCoalescingOperator1.ts, 39, 5)) +>d4 : Symbol(d4, Decl(nullishCoalescingOperator1.ts, 19, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator1.ts, 39, 19)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator1.types b/tests/baselines/reference/nullishCoalescingOperator1.types new file mode 100644 index 0000000000000..0e800540ee8b3 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator1.types @@ -0,0 +1,172 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator1.ts === +declare const a1: string | undefined | null +>a1 : string | null | undefined +>null : null + +declare const a2: string | undefined | null +>a2 : string | null | undefined +>null : null + +declare const a3: string | undefined | null +>a3 : string | null | undefined +>null : null + +declare const a4: string | undefined | null +>a4 : string | null | undefined +>null : null + +declare const b1: number | undefined | null +>b1 : number | null | undefined +>null : null + +declare const b2: number | undefined | null +>b2 : number | null | undefined +>null : null + +declare const b3: number | undefined | null +>b3 : number | null | undefined +>null : null + +declare const b4: number | undefined | null +>b4 : number | null | undefined +>null : null + +declare const c1: boolean | undefined | null +>c1 : boolean | null | undefined +>null : null + +declare const c2: boolean | undefined | null +>c2 : boolean | null | undefined +>null : null + +declare const c3: boolean | undefined | null +>c3 : boolean | null | undefined +>null : null + +declare const c4: boolean | undefined | null +>c4 : boolean | null | undefined +>null : null + +interface I { a: string } +>a : string + +declare const d1: I | undefined | null +>d1 : I | null | undefined +>null : null + +declare const d2: I | undefined | null +>d2 : I | null | undefined +>null : null + +declare const d3: I | undefined | null +>d3 : I | null | undefined +>null : null + +declare const d4: I | undefined | null +>d4 : I | null | undefined +>null : null + +const aa1 = a1 ?? 'whatever'; +>aa1 : string +>a1 ?? 'whatever' : string +>a1 : string | null | undefined +>'whatever' : "whatever" + +const aa2 = a2 ?? 'whatever'; +>aa2 : string +>a2 ?? 'whatever' : string +>a2 : string | null | undefined +>'whatever' : "whatever" + +const aa3 = a3 ?? 'whatever'; +>aa3 : string +>a3 ?? 'whatever' : string +>a3 : string | null | undefined +>'whatever' : "whatever" + +const aa4 = a4 ?? 'whatever'; +>aa4 : string +>a4 ?? 'whatever' : string +>a4 : string | null | undefined +>'whatever' : "whatever" + +const bb1 = b1 ?? 1; +>bb1 : number +>b1 ?? 1 : number +>b1 : number | null | undefined +>1 : 1 + +const bb2 = b2 ?? 1; +>bb2 : number +>b2 ?? 1 : number +>b2 : number | null | undefined +>1 : 1 + +const bb3 = b3 ?? 1; +>bb3 : number +>b3 ?? 1 : number +>b3 : number | null | undefined +>1 : 1 + +const bb4 = b4 ?? 1; +>bb4 : number +>b4 ?? 1 : number +>b4 : number | null | undefined +>1 : 1 + +const cc1 = c1 ?? true; +>cc1 : boolean +>c1 ?? true : boolean +>c1 : boolean | null | undefined +>true : true + +const cc2 = c2 ?? true; +>cc2 : boolean +>c2 ?? true : boolean +>c2 : boolean | null | undefined +>true : true + +const cc3 = c3 ?? true; +>cc3 : boolean +>c3 ?? true : boolean +>c3 : boolean | null | undefined +>true : true + +const cc4 = c4 ?? true; +>cc4 : boolean +>c4 ?? true : boolean +>c4 : boolean | null | undefined +>true : true + +const dd1 = d1 ?? {b: 1}; +>dd1 : I | { b: number; } +>d1 ?? {b: 1} : I | { b: number; } +>d1 : I | null | undefined +>{b: 1} : { b: number; } +>b : number +>1 : 1 + +const dd2 = d2 ?? {b: 1}; +>dd2 : I | { b: number; } +>d2 ?? {b: 1} : I | { b: number; } +>d2 : I | null | undefined +>{b: 1} : { b: number; } +>b : number +>1 : 1 + +const dd3 = d3 ?? {b: 1}; +>dd3 : I | { b: number; } +>d3 ?? {b: 1} : I | { b: number; } +>d3 : I | null | undefined +>{b: 1} : { b: number; } +>b : number +>1 : 1 + +const dd4 = d4 ?? {b: 1}; +>dd4 : I | { b: number; } +>d4 ?? {b: 1} : I | { b: number; } +>d4 : I | null | undefined +>{b: 1} : { b: number; } +>b : number +>1 : 1 + diff --git a/tests/baselines/reference/nullishCoalescingOperator10.js b/tests/baselines/reference/nullishCoalescingOperator10.js new file mode 100644 index 0000000000000..60556609fb576 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator10.js @@ -0,0 +1,11 @@ +//// [nullishCoalescingOperator10.ts] +declare function f(): string | undefined; + +let gg = f() ?? 'foo' + + + +//// [nullishCoalescingOperator10.js] +"use strict"; +var _a; +var gg = (_a = f(), (_a !== null && _a !== void 0 ? _a : 'foo')); diff --git a/tests/baselines/reference/nullishCoalescingOperator10.symbols b/tests/baselines/reference/nullishCoalescingOperator10.symbols new file mode 100644 index 0000000000000..7ee6248cf3093 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator10.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator10.ts === +declare function f(): string | undefined; +>f : Symbol(f, Decl(nullishCoalescingOperator10.ts, 0, 0)) + +let gg = f() ?? 'foo' +>gg : Symbol(gg, Decl(nullishCoalescingOperator10.ts, 2, 3)) +>f : Symbol(f, Decl(nullishCoalescingOperator10.ts, 0, 0)) + + diff --git a/tests/baselines/reference/nullishCoalescingOperator10.types b/tests/baselines/reference/nullishCoalescingOperator10.types new file mode 100644 index 0000000000000..4885f3717318c --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator10.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator10.ts === +declare function f(): string | undefined; +>f : () => string | undefined + +let gg = f() ?? 'foo' +>gg : string +>f() ?? 'foo' : string +>f() : string | undefined +>f : () => string | undefined +>'foo' : "foo" + + diff --git a/tests/baselines/reference/nullishCoalescingOperator11.errors.txt b/tests/baselines/reference/nullishCoalescingOperator11.errors.txt new file mode 100644 index 0000000000000..45faaea8767ac --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator11.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts(3,18): error TS2533: Object is possibly 'null' or 'undefined'. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts (1 errors) ==== + declare const f11: 1 | 0 | '' | null | undefined; + + let g11 = f11 ?? f11.toFixed() + ~~~ +!!! error TS2533: Object is possibly 'null' or 'undefined'. + + + \ No newline at end of file diff --git a/tests/baselines/reference/nullishCoalescingOperator11.js b/tests/baselines/reference/nullishCoalescingOperator11.js new file mode 100644 index 0000000000000..c716d1ce88b23 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator11.js @@ -0,0 +1,11 @@ +//// [nullishCoalescingOperator11.ts] +declare const f11: 1 | 0 | '' | null | undefined; + +let g11 = f11 ?? f11.toFixed() + + + + +//// [nullishCoalescingOperator11.js] +"use strict"; +var g11 = (f11 !== null && f11 !== void 0 ? f11 : f11.toFixed()); diff --git a/tests/baselines/reference/nullishCoalescingOperator11.symbols b/tests/baselines/reference/nullishCoalescingOperator11.symbols new file mode 100644 index 0000000000000..a6f8240be66c9 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator11.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts === +declare const f11: 1 | 0 | '' | null | undefined; +>f11 : Symbol(f11, Decl(nullishCoalescingOperator11.ts, 0, 13)) + +let g11 = f11 ?? f11.toFixed() +>g11 : Symbol(g11, Decl(nullishCoalescingOperator11.ts, 2, 3)) +>f11 : Symbol(f11, Decl(nullishCoalescingOperator11.ts, 0, 13)) +>f11 : Symbol(f11, Decl(nullishCoalescingOperator11.ts, 0, 13)) + + + diff --git a/tests/baselines/reference/nullishCoalescingOperator11.types b/tests/baselines/reference/nullishCoalescingOperator11.types new file mode 100644 index 0000000000000..5c168dd463271 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator11.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts === +declare const f11: 1 | 0 | '' | null | undefined; +>f11 : "" | 0 | 1 | null | undefined +>null : null + +let g11 = f11 ?? f11.toFixed() +>g11 : any +>f11 ?? f11.toFixed() : any +>f11 : "" | 0 | 1 | null | undefined +>f11.toFixed() : any +>f11.toFixed : any +>f11 : null | undefined +>toFixed : any + + + diff --git a/tests/baselines/reference/nullishCoalescingOperator2.js b/tests/baselines/reference/nullishCoalescingOperator2.js new file mode 100644 index 0000000000000..e36a526c04842 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator2.js @@ -0,0 +1,33 @@ +//// [nullishCoalescingOperator2.ts] +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null +declare const a7: unknown | null +declare const a8: never | null +declare const a9: any | null + + +const aa1 = a1 ?? 'whatever' +const aa2 = a2 ?? 'whatever' +const aa3 = a3 ?? 'whatever' +const aa4 = a4 ?? 'whatever' +const aa5 = a5 ?? 'whatever' +const aa6 = a6 ?? 'whatever' +const aa7 = a7 ?? 'whatever' +const aa8 = a8 ?? 'whatever' +const aa9 = a9 ?? 'whatever' + +//// [nullishCoalescingOperator2.js] +"use strict"; +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'); +var aa4 = (a4 !== null && a4 !== void 0 ? a4 : 'whatever'); +var aa5 = (a5 !== null && a5 !== void 0 ? a5 : 'whatever'); +var aa6 = (a6 !== null && a6 !== void 0 ? a6 : 'whatever'); +var aa7 = (a7 !== null && a7 !== void 0 ? a7 : 'whatever'); +var aa8 = (a8 !== null && a8 !== void 0 ? a8 : 'whatever'); +var aa9 = (a9 !== null && a9 !== void 0 ? a9 : 'whatever'); diff --git a/tests/baselines/reference/nullishCoalescingOperator2.symbols b/tests/baselines/reference/nullishCoalescingOperator2.symbols new file mode 100644 index 0000000000000..d712165683405 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator2.symbols @@ -0,0 +1,65 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator2.ts === +declare const a1: 'literal' | undefined | null +>a1 : Symbol(a1, Decl(nullishCoalescingOperator2.ts, 0, 13)) + +declare const a2: '' | undefined | null +>a2 : Symbol(a2, Decl(nullishCoalescingOperator2.ts, 1, 13)) + +declare const a3: 1 | undefined | null +>a3 : Symbol(a3, Decl(nullishCoalescingOperator2.ts, 2, 13)) + +declare const a4: 0 | undefined | null +>a4 : Symbol(a4, Decl(nullishCoalescingOperator2.ts, 3, 13)) + +declare const a5: true | undefined | null +>a5 : Symbol(a5, Decl(nullishCoalescingOperator2.ts, 4, 13)) + +declare const a6: false | undefined | null +>a6 : Symbol(a6, Decl(nullishCoalescingOperator2.ts, 5, 13)) + +declare const a7: unknown | null +>a7 : Symbol(a7, Decl(nullishCoalescingOperator2.ts, 6, 13)) + +declare const a8: never | null +>a8 : Symbol(a8, Decl(nullishCoalescingOperator2.ts, 7, 13)) + +declare const a9: any | null +>a9 : Symbol(a9, Decl(nullishCoalescingOperator2.ts, 8, 13)) + + +const aa1 = a1 ?? 'whatever' +>aa1 : Symbol(aa1, Decl(nullishCoalescingOperator2.ts, 11, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator2.ts, 0, 13)) + +const aa2 = a2 ?? 'whatever' +>aa2 : Symbol(aa2, Decl(nullishCoalescingOperator2.ts, 12, 5)) +>a2 : Symbol(a2, Decl(nullishCoalescingOperator2.ts, 1, 13)) + +const aa3 = a3 ?? 'whatever' +>aa3 : Symbol(aa3, Decl(nullishCoalescingOperator2.ts, 13, 5)) +>a3 : Symbol(a3, Decl(nullishCoalescingOperator2.ts, 2, 13)) + +const aa4 = a4 ?? 'whatever' +>aa4 : Symbol(aa4, Decl(nullishCoalescingOperator2.ts, 14, 5)) +>a4 : Symbol(a4, Decl(nullishCoalescingOperator2.ts, 3, 13)) + +const aa5 = a5 ?? 'whatever' +>aa5 : Symbol(aa5, Decl(nullishCoalescingOperator2.ts, 15, 5)) +>a5 : Symbol(a5, Decl(nullishCoalescingOperator2.ts, 4, 13)) + +const aa6 = a6 ?? 'whatever' +>aa6 : Symbol(aa6, Decl(nullishCoalescingOperator2.ts, 16, 5)) +>a6 : Symbol(a6, Decl(nullishCoalescingOperator2.ts, 5, 13)) + +const aa7 = a7 ?? 'whatever' +>aa7 : Symbol(aa7, Decl(nullishCoalescingOperator2.ts, 17, 5)) +>a7 : Symbol(a7, Decl(nullishCoalescingOperator2.ts, 6, 13)) + +const aa8 = a8 ?? 'whatever' +>aa8 : Symbol(aa8, Decl(nullishCoalescingOperator2.ts, 18, 5)) +>a8 : Symbol(a8, Decl(nullishCoalescingOperator2.ts, 7, 13)) + +const aa9 = a9 ?? 'whatever' +>aa9 : Symbol(aa9, Decl(nullishCoalescingOperator2.ts, 19, 5)) +>a9 : Symbol(a9, Decl(nullishCoalescingOperator2.ts, 8, 13)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator2.types b/tests/baselines/reference/nullishCoalescingOperator2.types new file mode 100644 index 0000000000000..dd1e31c4038c4 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator2.types @@ -0,0 +1,94 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator2.ts === +declare const a1: 'literal' | undefined | null +>a1 : "literal" | null | undefined +>null : null + +declare const a2: '' | undefined | null +>a2 : "" | null | undefined +>null : null + +declare const a3: 1 | undefined | null +>a3 : 1 | null | undefined +>null : null + +declare const a4: 0 | undefined | null +>a4 : 0 | null | undefined +>null : null + +declare const a5: true | undefined | null +>a5 : true | null | undefined +>true : true +>null : null + +declare const a6: false | undefined | null +>a6 : false | null | undefined +>false : false +>null : null + +declare const a7: unknown | null +>a7 : unknown +>null : null + +declare const a8: never | null +>a8 : null +>null : null + +declare const a9: any | null +>a9 : any +>null : null + + +const aa1 = a1 ?? 'whatever' +>aa1 : "literal" | "whatever" +>a1 ?? 'whatever' : "literal" | "whatever" +>a1 : "literal" | null | undefined +>'whatever' : "whatever" + +const aa2 = a2 ?? 'whatever' +>aa2 : "" | "whatever" +>a2 ?? 'whatever' : "" | "whatever" +>a2 : "" | null | undefined +>'whatever' : "whatever" + +const aa3 = a3 ?? 'whatever' +>aa3 : 1 | "whatever" +>a3 ?? 'whatever' : 1 | "whatever" +>a3 : 1 | null | undefined +>'whatever' : "whatever" + +const aa4 = a4 ?? 'whatever' +>aa4 : 0 | "whatever" +>a4 ?? 'whatever' : 0 | "whatever" +>a4 : 0 | null | undefined +>'whatever' : "whatever" + +const aa5 = a5 ?? 'whatever' +>aa5 : true | "whatever" +>a5 ?? 'whatever' : true | "whatever" +>a5 : true | null | undefined +>'whatever' : "whatever" + +const aa6 = a6 ?? 'whatever' +>aa6 : false | "whatever" +>a6 ?? 'whatever' : false | "whatever" +>a6 : false | null | undefined +>'whatever' : "whatever" + +const aa7 = a7 ?? 'whatever' +>aa7 : unknown +>a7 ?? 'whatever' : unknown +>a7 : unknown +>'whatever' : "whatever" + +const aa8 = a8 ?? 'whatever' +>aa8 : "whatever" +>a8 ?? 'whatever' : "whatever" +>a8 : null +>'whatever' : "whatever" + +const aa9 = a9 ?? 'whatever' +>aa9 : any +>a9 ?? 'whatever' : any +>a9 : any +>'whatever' : "whatever" + diff --git a/tests/baselines/reference/nullishCoalescingOperator3.js b/tests/baselines/reference/nullishCoalescingOperator3.js new file mode 100644 index 0000000000000..c0f56552433a0 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator3.js @@ -0,0 +1,16 @@ +//// [nullishCoalescingOperator3.ts] +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null + + +const aa1 = a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 ?? 'whatever' + + +//// [nullishCoalescingOperator3.js] +"use strict"; +var _a, _b, _c, _d, _e; +var aa1 = (_e = (_d = (_c = (_b = (_a = (a1 !== null && a1 !== void 0 ? a1 : a2), (_a !== null && _a !== void 0 ? _a : a3)), (_b !== null && _b !== void 0 ? _b : a4)), (_c !== null && _c !== void 0 ? _c : a5)), (_d !== null && _d !== void 0 ? _d : a6)), (_e !== null && _e !== void 0 ? _e : 'whatever')); diff --git a/tests/baselines/reference/nullishCoalescingOperator3.symbols b/tests/baselines/reference/nullishCoalescingOperator3.symbols new file mode 100644 index 0000000000000..5f9e5a7c3a549 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator3.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator3.ts === +declare const a1: 'literal' | undefined | null +>a1 : Symbol(a1, Decl(nullishCoalescingOperator3.ts, 0, 13)) + +declare const a2: '' | undefined | null +>a2 : Symbol(a2, Decl(nullishCoalescingOperator3.ts, 1, 13)) + +declare const a3: 1 | undefined | null +>a3 : Symbol(a3, Decl(nullishCoalescingOperator3.ts, 2, 13)) + +declare const a4: 0 | undefined | null +>a4 : Symbol(a4, Decl(nullishCoalescingOperator3.ts, 3, 13)) + +declare const a5: true | undefined | null +>a5 : Symbol(a5, Decl(nullishCoalescingOperator3.ts, 4, 13)) + +declare const a6: false | undefined | null +>a6 : Symbol(a6, Decl(nullishCoalescingOperator3.ts, 5, 13)) + + +const aa1 = a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 ?? 'whatever' +>aa1 : Symbol(aa1, Decl(nullishCoalescingOperator3.ts, 8, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator3.ts, 0, 13)) +>a2 : Symbol(a2, Decl(nullishCoalescingOperator3.ts, 1, 13)) +>a3 : Symbol(a3, Decl(nullishCoalescingOperator3.ts, 2, 13)) +>a4 : Symbol(a4, Decl(nullishCoalescingOperator3.ts, 3, 13)) +>a5 : Symbol(a5, Decl(nullishCoalescingOperator3.ts, 4, 13)) +>a6 : Symbol(a6, Decl(nullishCoalescingOperator3.ts, 5, 13)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator3.types b/tests/baselines/reference/nullishCoalescingOperator3.types new file mode 100644 index 0000000000000..3f725c8c772a2 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator3.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator3.ts === +declare const a1: 'literal' | undefined | null +>a1 : "literal" | null | undefined +>null : null + +declare const a2: '' | undefined | null +>a2 : "" | null | undefined +>null : null + +declare const a3: 1 | undefined | null +>a3 : 1 | null | undefined +>null : null + +declare const a4: 0 | undefined | null +>a4 : 0 | null | undefined +>null : null + +declare const a5: true | undefined | null +>a5 : true | null | undefined +>true : true +>null : null + +declare const a6: false | undefined | null +>a6 : false | null | undefined +>false : false +>null : null + + +const aa1 = a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 ?? 'whatever' +>aa1 : boolean | "" | 0 | "literal" | 1 | "whatever" +>a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 ?? 'whatever' : boolean | "" | 0 | "literal" | 1 | "whatever" +>a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 : boolean | "" | 0 | "literal" | 1 | null | undefined +>a1 ?? a2 ?? a3 ?? a4 ?? a5 : true | "" | 0 | "literal" | 1 | null | undefined +>a1 ?? a2 ?? a3 ?? a4 : "" | 0 | "literal" | 1 | null | undefined +>a1 ?? a2 ?? a3 : "" | "literal" | 1 | null | undefined +>a1 ?? a2 : "" | "literal" | null | undefined +>a1 : "literal" | null | undefined +>a2 : "" | null | undefined +>a3 : 1 | null | undefined +>a4 : 0 | null | undefined +>a5 : true | null | undefined +>a6 : false | null | undefined +>'whatever' : "whatever" + diff --git a/tests/baselines/reference/nullishCoalescingOperator4.errors.txt b/tests/baselines/reference/nullishCoalescingOperator4.errors.txt new file mode 100644 index 0000000000000..ba8ad2e7ac7c3 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator4.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts(2,19): error TS2533: Object is possibly 'null' or 'undefined'. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts(3,19): error TS2533: Object is possibly 'null' or 'undefined'. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts (2 errors) ==== + declare const a1: 'literal' | undefined | null + const aa1 = a1 ?? a1.toLowerCase() + ~~ +!!! error TS2533: Object is possibly 'null' or 'undefined'. + const aa2 = a1 || a1.toLocaleUpperCase() + ~~ +!!! error TS2533: Object is possibly 'null' or 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/nullishCoalescingOperator4.js b/tests/baselines/reference/nullishCoalescingOperator4.js new file mode 100644 index 0000000000000..0018a3880cf03 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator4.js @@ -0,0 +1,10 @@ +//// [nullishCoalescingOperator4.ts] +declare const a1: 'literal' | undefined | null +const aa1 = a1 ?? a1.toLowerCase() +const aa2 = a1 || a1.toLocaleUpperCase() + + +//// [nullishCoalescingOperator4.js] +"use strict"; +var aa1 = (a1 !== null && a1 !== void 0 ? a1 : a1.toLowerCase()); +var aa2 = a1 || a1.toLocaleUpperCase(); diff --git a/tests/baselines/reference/nullishCoalescingOperator4.symbols b/tests/baselines/reference/nullishCoalescingOperator4.symbols new file mode 100644 index 0000000000000..ec83f771d04a7 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator4.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts === +declare const a1: 'literal' | undefined | null +>a1 : Symbol(a1, Decl(nullishCoalescingOperator4.ts, 0, 13)) + +const aa1 = a1 ?? a1.toLowerCase() +>aa1 : Symbol(aa1, Decl(nullishCoalescingOperator4.ts, 1, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator4.ts, 0, 13)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator4.ts, 0, 13)) + +const aa2 = a1 || a1.toLocaleUpperCase() +>aa2 : Symbol(aa2, Decl(nullishCoalescingOperator4.ts, 2, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator4.ts, 0, 13)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator4.ts, 0, 13)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator4.types b/tests/baselines/reference/nullishCoalescingOperator4.types new file mode 100644 index 0000000000000..8ac9111c009a2 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator4.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts === +declare const a1: 'literal' | undefined | null +>a1 : "literal" | null | undefined +>null : null + +const aa1 = a1 ?? a1.toLowerCase() +>aa1 : any +>a1 ?? a1.toLowerCase() : any +>a1 : "literal" | null | undefined +>a1.toLowerCase() : any +>a1.toLowerCase : any +>a1 : null | undefined +>toLowerCase : any + +const aa2 = a1 || a1.toLocaleUpperCase() +>aa2 : any +>a1 || a1.toLocaleUpperCase() : any +>a1 : "literal" | null | undefined +>a1.toLocaleUpperCase() : any +>a1.toLocaleUpperCase : any +>a1 : null | undefined +>toLocaleUpperCase : any + diff --git a/tests/baselines/reference/nullishCoalescingOperator5.errors.txt b/tests/baselines/reference/nullishCoalescingOperator5.errors.txt new file mode 100644 index 0000000000000..f5a0c68bf251b --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator5.errors.txt @@ -0,0 +1,55 @@ +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts(6,6): error TS5076: '||' and '??' operations cannot be mixed without parentheses. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts(9,1): error TS5076: '||' and '??' operations cannot be mixed without parentheses. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts(12,6): error TS5076: '&&' and '??' operations cannot be mixed without parentheses. +tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts(15,1): error TS5076: '&&' and '??' operations cannot be mixed without parentheses. + + +==== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts (4 errors) ==== + declare const a: string | undefined + declare const b: string | undefined + declare const c: string | undefined + + // should be a syntax error + a ?? b || c; + ~~~~~~ +!!! error TS5076: '||' and '??' operations cannot be mixed without parentheses. + + // should be a syntax error + a || b ?? c; + ~~~~~~ +!!! error TS5076: '||' and '??' operations cannot be mixed without parentheses. + + // should be a syntax error + a ?? b && c; + ~~~~~~ +!!! error TS5076: '&&' and '??' operations cannot be mixed without parentheses. + + // should be a syntax error + a && b ?? c; + ~~~~~~ +!!! error TS5076: '&&' and '??' operations cannot be mixed without parentheses. + + // Valid according to spec + a ?? (b || c); + + // Valid according to spec + (a ?? b) || c; + + // Valid according to spec + (a || b) ?? c; + + // Valid according to spec + a || (b ?? c); + + // Valid according to spec + a ?? (b && c); + + // Valid according to spec + (a ?? b) && c; + + // Valid according to spec + (a && b) ?? c; + + // Valid according to spec + a && (b ?? c); + \ No newline at end of file diff --git a/tests/baselines/reference/nullishCoalescingOperator5.js b/tests/baselines/reference/nullishCoalescingOperator5.js new file mode 100644 index 0000000000000..c74f3da0827b1 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator5.js @@ -0,0 +1,69 @@ +//// [nullishCoalescingOperator5.ts] +declare const a: string | undefined +declare const b: string | undefined +declare const c: string | undefined + +// should be a syntax error +a ?? b || c; + +// should be a syntax error +a || b ?? c; + +// should be a syntax error +a ?? b && c; + +// should be a syntax error +a && b ?? c; + +// Valid according to spec +a ?? (b || c); + +// Valid according to spec +(a ?? b) || c; + +// Valid according to spec +(a || b) ?? c; + +// Valid according to spec +a || (b ?? c); + +// Valid according to spec +a ?? (b && c); + +// Valid according to spec +(a ?? b) && c; + +// Valid according to spec +(a && b) ?? c; + +// Valid according to spec +a && (b ?? c); + + +//// [nullishCoalescingOperator5.js] +"use strict"; +var _a, _b, _c, _d; +// should be a syntax error +(a !== null && a !== void 0 ? a : b || c); +// should be a syntax error +_a = a || b, (_a !== null && _a !== void 0 ? _a : c); +// should be a syntax error +(a !== null && a !== void 0 ? a : b && c); +// should be a syntax error +_b = a && b, (_b !== null && _b !== void 0 ? _b : c); +// Valid according to spec +(a !== null && a !== void 0 ? a : (b || c)); +// Valid according to spec +((a !== null && a !== void 0 ? a : b)) || c; +// Valid according to spec +_c = (a || b), (_c !== null && _c !== void 0 ? _c : c); +// Valid according to spec +a || ((b !== null && b !== void 0 ? b : c)); +// Valid according to spec +(a !== null && a !== void 0 ? a : (b && c)); +// Valid according to spec +((a !== null && a !== void 0 ? a : b)) && c; +// Valid according to spec +_d = (a && b), (_d !== null && _d !== void 0 ? _d : c); +// Valid according to spec +a && ((b !== null && b !== void 0 ? b : c)); diff --git a/tests/baselines/reference/nullishCoalescingOperator5.symbols b/tests/baselines/reference/nullishCoalescingOperator5.symbols new file mode 100644 index 0000000000000..d073c91fbc503 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator5.symbols @@ -0,0 +1,82 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts === +declare const a: string | undefined +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) + +declare const b: string | undefined +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) + +declare const c: string | undefined +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// should be a syntax error +a ?? b || c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// should be a syntax error +a || b ?? c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// should be a syntax error +a ?? b && c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// should be a syntax error +a && b ?? c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +a ?? (b || c); +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +(a ?? b) || c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +(a || b) ?? c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +a || (b ?? c); +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +a ?? (b && c); +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +(a ?? b) && c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +(a && b) ?? c; +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + +// Valid according to spec +a && (b ?? c); +>a : Symbol(a, Decl(nullishCoalescingOperator5.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator5.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator5.ts, 2, 13)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator5.types b/tests/baselines/reference/nullishCoalescingOperator5.types new file mode 100644 index 0000000000000..bbf526d774339 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator5.types @@ -0,0 +1,114 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts === +declare const a: string | undefined +>a : string | undefined + +declare const b: string | undefined +>b : string | undefined + +declare const c: string | undefined +>c : string | undefined + +// should be a syntax error +a ?? b || c; +>a ?? b || c : string | undefined +>a : string | undefined +>b || c : string | undefined +>b : string | undefined +>c : string | undefined + +// should be a syntax error +a || b ?? c; +>a || b ?? c : string | undefined +>a || b : string | undefined +>a : string | undefined +>b : string | undefined +>c : string | undefined + +// should be a syntax error +a ?? b && c; +>a ?? b && c : string | undefined +>a : string | undefined +>b && c : string | undefined +>b : string | undefined +>c : string | undefined + +// should be a syntax error +a && b ?? c; +>a && b ?? c : string | undefined +>a && b : string | undefined +>a : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +a ?? (b || c); +>a ?? (b || c) : string | undefined +>a : string | undefined +>(b || c) : string | undefined +>b || c : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +(a ?? b) || c; +>(a ?? b) || c : string | undefined +>(a ?? b) : string | undefined +>a ?? b : string | undefined +>a : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +(a || b) ?? c; +>(a || b) ?? c : string | undefined +>(a || b) : string | undefined +>a || b : string | undefined +>a : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +a || (b ?? c); +>a || (b ?? c) : string | undefined +>a : string | undefined +>(b ?? c) : string | undefined +>b ?? c : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +a ?? (b && c); +>a ?? (b && c) : string | undefined +>a : string | undefined +>(b && c) : string | undefined +>b && c : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +(a ?? b) && c; +>(a ?? b) && c : string | undefined +>(a ?? b) : string | undefined +>a ?? b : string | undefined +>a : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +(a && b) ?? c; +>(a && b) ?? c : string | undefined +>(a && b) : string | undefined +>a && b : string | undefined +>a : string | undefined +>b : string | undefined +>c : string | undefined + +// Valid according to spec +a && (b ?? c); +>a && (b ?? c) : string | undefined +>a : string | undefined +>(b ?? c) : string | undefined +>b ?? c : string | undefined +>b : string | undefined +>c : string | undefined + diff --git a/tests/baselines/reference/nullishCoalescingOperator6.js b/tests/baselines/reference/nullishCoalescingOperator6.js new file mode 100644 index 0000000000000..698ccb311b62b --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator6.js @@ -0,0 +1,9 @@ +//// [nullishCoalescingOperator6.ts] +function foo(foo: string, bar = foo ?? "bar") { } + + +//// [nullishCoalescingOperator6.js] +"use strict"; +function foo(foo, bar) { + if (bar === void 0) { bar = (foo !== null && foo !== void 0 ? foo : "bar"); } +} diff --git a/tests/baselines/reference/nullishCoalescingOperator6.symbols b/tests/baselines/reference/nullishCoalescingOperator6.symbols new file mode 100644 index 0000000000000..41ec5d1c28c0f --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator6.symbols @@ -0,0 +1,7 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator6.ts === +function foo(foo: string, bar = foo ?? "bar") { } +>foo : Symbol(foo, Decl(nullishCoalescingOperator6.ts, 0, 0)) +>foo : Symbol(foo, Decl(nullishCoalescingOperator6.ts, 0, 13)) +>bar : Symbol(bar, Decl(nullishCoalescingOperator6.ts, 0, 25)) +>foo : Symbol(foo, Decl(nullishCoalescingOperator6.ts, 0, 13)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator6.types b/tests/baselines/reference/nullishCoalescingOperator6.types new file mode 100644 index 0000000000000..8bc738ab5fe42 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator6.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator6.ts === +function foo(foo: string, bar = foo ?? "bar") { } +>foo : (foo: string, bar?: string) => void +>foo : string +>bar : string +>foo ?? "bar" : string +>foo : string +>"bar" : "bar" + diff --git a/tests/baselines/reference/nullishCoalescingOperator7.js b/tests/baselines/reference/nullishCoalescingOperator7.js new file mode 100644 index 0000000000000..443ec066ea5a1 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator7.js @@ -0,0 +1,22 @@ +//// [nullishCoalescingOperator7.ts] +declare const a: string | undefined; +declare const b: string | undefined; +declare const c: string | undefined; + +const foo1 = a ? 1 : 2; +const foo2 = a ?? 'foo' ? 1 : 2; +const foo3 = a ?? 'foo' ? (b ?? 'bar') : (c ?? 'baz'); + +function f () { + const foo4 = a ?? 'foo' ? b ?? 'bar' : c ?? 'baz'; +} + + +//// [nullishCoalescingOperator7.js] +"use strict"; +var foo1 = a ? 1 : 2; +var foo2 = (a !== null && a !== void 0 ? a : 'foo') ? 1 : 2; +var foo3 = (a !== null && a !== void 0 ? a : 'foo') ? ((b !== null && b !== void 0 ? b : 'bar')) : ((c !== null && c !== void 0 ? c : 'baz')); +function f() { + var foo4 = (a !== null && a !== void 0 ? a : 'foo') ? (b !== null && b !== void 0 ? b : 'bar') : (c !== null && c !== void 0 ? c : 'baz'); +} diff --git a/tests/baselines/reference/nullishCoalescingOperator7.symbols b/tests/baselines/reference/nullishCoalescingOperator7.symbols new file mode 100644 index 0000000000000..89fc9aaec3f03 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator7.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator7.ts === +declare const a: string | undefined; +>a : Symbol(a, Decl(nullishCoalescingOperator7.ts, 0, 13)) + +declare const b: string | undefined; +>b : Symbol(b, Decl(nullishCoalescingOperator7.ts, 1, 13)) + +declare const c: string | undefined; +>c : Symbol(c, Decl(nullishCoalescingOperator7.ts, 2, 13)) + +const foo1 = a ? 1 : 2; +>foo1 : Symbol(foo1, Decl(nullishCoalescingOperator7.ts, 4, 5)) +>a : Symbol(a, Decl(nullishCoalescingOperator7.ts, 0, 13)) + +const foo2 = a ?? 'foo' ? 1 : 2; +>foo2 : Symbol(foo2, Decl(nullishCoalescingOperator7.ts, 5, 5)) +>a : Symbol(a, Decl(nullishCoalescingOperator7.ts, 0, 13)) + +const foo3 = a ?? 'foo' ? (b ?? 'bar') : (c ?? 'baz'); +>foo3 : Symbol(foo3, Decl(nullishCoalescingOperator7.ts, 6, 5)) +>a : Symbol(a, Decl(nullishCoalescingOperator7.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator7.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator7.ts, 2, 13)) + +function f () { +>f : Symbol(f, Decl(nullishCoalescingOperator7.ts, 6, 54)) + + const foo4 = a ?? 'foo' ? b ?? 'bar' : c ?? 'baz'; +>foo4 : Symbol(foo4, Decl(nullishCoalescingOperator7.ts, 9, 9)) +>a : Symbol(a, Decl(nullishCoalescingOperator7.ts, 0, 13)) +>b : Symbol(b, Decl(nullishCoalescingOperator7.ts, 1, 13)) +>c : Symbol(c, Decl(nullishCoalescingOperator7.ts, 2, 13)) +} + diff --git a/tests/baselines/reference/nullishCoalescingOperator7.types b/tests/baselines/reference/nullishCoalescingOperator7.types new file mode 100644 index 0000000000000..a465779625dfd --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator7.types @@ -0,0 +1,58 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator7.ts === +declare const a: string | undefined; +>a : string | undefined + +declare const b: string | undefined; +>b : string | undefined + +declare const c: string | undefined; +>c : string | undefined + +const foo1 = a ? 1 : 2; +>foo1 : 1 | 2 +>a ? 1 : 2 : 1 | 2 +>a : string | undefined +>1 : 1 +>2 : 2 + +const foo2 = a ?? 'foo' ? 1 : 2; +>foo2 : 1 | 2 +>a ?? 'foo' ? 1 : 2 : 1 | 2 +>a ?? 'foo' : string +>a : string | undefined +>'foo' : "foo" +>1 : 1 +>2 : 2 + +const foo3 = a ?? 'foo' ? (b ?? 'bar') : (c ?? 'baz'); +>foo3 : string +>a ?? 'foo' ? (b ?? 'bar') : (c ?? 'baz') : string +>a ?? 'foo' : string +>a : string | undefined +>'foo' : "foo" +>(b ?? 'bar') : string +>b ?? 'bar' : string +>b : string | undefined +>'bar' : "bar" +>(c ?? 'baz') : string +>c ?? 'baz' : string +>c : string | undefined +>'baz' : "baz" + +function f () { +>f : () => void + + const foo4 = a ?? 'foo' ? b ?? 'bar' : c ?? 'baz'; +>foo4 : string +>a ?? 'foo' ? b ?? 'bar' : c ?? 'baz' : string +>a ?? 'foo' : string +>a : string | undefined +>'foo' : "foo" +>b ?? 'bar' : string +>b : string | undefined +>'bar' : "bar" +>c ?? 'baz' : string +>c : string | undefined +>'baz' : "baz" +} + diff --git a/tests/baselines/reference/nullishCoalescingOperator8.js b/tests/baselines/reference/nullishCoalescingOperator8.js new file mode 100644 index 0000000000000..3b56a1de01006 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator8.js @@ -0,0 +1,16 @@ +//// [nullishCoalescingOperator8.ts] +declare const a: { p: string | undefined, m(): string | undefined }; +declare const b: { p: string | undefined, m(): string | undefined }; + +const n1 = a.p ?? "default"; +const n2 = a.m() ?? "default"; +const n3 = a.m() ?? b.p ?? b.m() ?? "default";; + + +//// [nullishCoalescingOperator8.js] +"use strict"; +var _a, _b, _c, _d, _e; +var n1 = (_a = a.p, (_a !== null && _a !== void 0 ? _a : "default")); +var n2 = (_b = a.m(), (_b !== null && _b !== void 0 ? _b : "default")); +var n3 = (_e = (_d = (_c = a.m(), (_c !== null && _c !== void 0 ? _c : b.p)), (_d !== null && _d !== void 0 ? _d : b.m())), (_e !== null && _e !== void 0 ? _e : "default")); +; diff --git a/tests/baselines/reference/nullishCoalescingOperator8.symbols b/tests/baselines/reference/nullishCoalescingOperator8.symbols new file mode 100644 index 0000000000000..40d881cb99e51 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator8.symbols @@ -0,0 +1,35 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts === +declare const a: { p: string | undefined, m(): string | undefined }; +>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13)) +>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 0, 18)) +>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41)) + +declare const b: { p: string | undefined, m(): string | undefined }; +>b : Symbol(b, Decl(nullishCoalescingOperator8.ts, 1, 13)) +>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 1, 18)) +>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 1, 41)) + +const n1 = a.p ?? "default"; +>n1 : Symbol(n1, Decl(nullishCoalescingOperator8.ts, 3, 5)) +>a.p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 0, 18)) +>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13)) +>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 0, 18)) + +const n2 = a.m() ?? "default"; +>n2 : Symbol(n2, Decl(nullishCoalescingOperator8.ts, 4, 5)) +>a.m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41)) +>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13)) +>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41)) + +const n3 = a.m() ?? b.p ?? b.m() ?? "default";; +>n3 : Symbol(n3, Decl(nullishCoalescingOperator8.ts, 5, 5)) +>a.m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41)) +>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13)) +>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41)) +>b.p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 1, 18)) +>b : Symbol(b, Decl(nullishCoalescingOperator8.ts, 1, 13)) +>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 1, 18)) +>b.m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 1, 41)) +>b : Symbol(b, Decl(nullishCoalescingOperator8.ts, 1, 13)) +>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 1, 41)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator8.types b/tests/baselines/reference/nullishCoalescingOperator8.types new file mode 100644 index 0000000000000..09d85f291e4af --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator8.types @@ -0,0 +1,46 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts === +declare const a: { p: string | undefined, m(): string | undefined }; +>a : { p: string | undefined; m(): string | undefined; } +>p : string | undefined +>m : () => string | undefined + +declare const b: { p: string | undefined, m(): string | undefined }; +>b : { p: string | undefined; m(): string | undefined; } +>p : string | undefined +>m : () => string | undefined + +const n1 = a.p ?? "default"; +>n1 : string +>a.p ?? "default" : string +>a.p : string | undefined +>a : { p: string | undefined; m(): string | undefined; } +>p : string | undefined +>"default" : "default" + +const n2 = a.m() ?? "default"; +>n2 : string +>a.m() ?? "default" : string +>a.m() : string | undefined +>a.m : () => string | undefined +>a : { p: string | undefined; m(): string | undefined; } +>m : () => string | undefined +>"default" : "default" + +const n3 = a.m() ?? b.p ?? b.m() ?? "default";; +>n3 : string +>a.m() ?? b.p ?? b.m() ?? "default" : string +>a.m() ?? b.p ?? b.m() : string | undefined +>a.m() ?? b.p : string | undefined +>a.m() : string | undefined +>a.m : () => string | undefined +>a : { p: string | undefined; m(): string | undefined; } +>m : () => string | undefined +>b.p : string | undefined +>b : { p: string | undefined; m(): string | undefined; } +>p : string | undefined +>b.m() : string | undefined +>b.m : () => string | undefined +>b : { p: string | undefined; m(): string | undefined; } +>m : () => string | undefined +>"default" : "default" + diff --git a/tests/baselines/reference/nullishCoalescingOperator9.js b/tests/baselines/reference/nullishCoalescingOperator9.js new file mode 100644 index 0000000000000..a547d28911a86 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator9.js @@ -0,0 +1,11 @@ +//// [nullishCoalescingOperator9.ts] +declare let f: null | ((x: string) => void); + +let g = f || (abc => { void abc.toLowerCase() }) +let gg = f ?? (abc => { void abc.toLowerCase() }) + + +//// [nullishCoalescingOperator9.js] +"use strict"; +var g = f || (function (abc) { void abc.toLowerCase(); }); +var gg = (f !== null && f !== void 0 ? f : (function (abc) { void abc.toLowerCase(); })); diff --git a/tests/baselines/reference/nullishCoalescingOperator9.symbols b/tests/baselines/reference/nullishCoalescingOperator9.symbols new file mode 100644 index 0000000000000..e1006af93447b --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator9.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator9.ts === +declare let f: null | ((x: string) => void); +>f : Symbol(f, Decl(nullishCoalescingOperator9.ts, 0, 11)) +>x : Symbol(x, Decl(nullishCoalescingOperator9.ts, 0, 24)) + +let g = f || (abc => { void abc.toLowerCase() }) +>g : Symbol(g, Decl(nullishCoalescingOperator9.ts, 2, 3)) +>f : Symbol(f, Decl(nullishCoalescingOperator9.ts, 0, 11)) +>abc : Symbol(abc, Decl(nullishCoalescingOperator9.ts, 2, 14)) +>abc.toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) +>abc : Symbol(abc, Decl(nullishCoalescingOperator9.ts, 2, 14)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) + +let gg = f ?? (abc => { void abc.toLowerCase() }) +>gg : Symbol(gg, Decl(nullishCoalescingOperator9.ts, 3, 3)) +>f : Symbol(f, Decl(nullishCoalescingOperator9.ts, 0, 11)) +>abc : Symbol(abc, Decl(nullishCoalescingOperator9.ts, 3, 15)) +>abc.toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) +>abc : Symbol(abc, Decl(nullishCoalescingOperator9.ts, 3, 15)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator9.types b/tests/baselines/reference/nullishCoalescingOperator9.types new file mode 100644 index 0000000000000..e03ad4221ea60 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator9.types @@ -0,0 +1,32 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator9.ts === +declare let f: null | ((x: string) => void); +>f : ((x: string) => void) | null +>null : null +>x : string + +let g = f || (abc => { void abc.toLowerCase() }) +>g : (x: string) => void +>f || (abc => { void abc.toLowerCase() }) : (x: string) => void +>f : ((x: string) => void) | null +>(abc => { void abc.toLowerCase() }) : (abc: string) => void +>abc => { void abc.toLowerCase() } : (abc: string) => void +>abc : string +>void abc.toLowerCase() : undefined +>abc.toLowerCase() : string +>abc.toLowerCase : () => string +>abc : string +>toLowerCase : () => string + +let gg = f ?? (abc => { void abc.toLowerCase() }) +>gg : (x: string) => void +>f ?? (abc => { void abc.toLowerCase() }) : (x: string) => void +>f : ((x: string) => void) | null +>(abc => { void abc.toLowerCase() }) : (abc: string) => void +>abc => { void abc.toLowerCase() } : (abc: string) => void +>abc : string +>void abc.toLowerCase() : undefined +>abc.toLowerCase() : string +>abc.toLowerCase : () => string +>abc : string +>toLowerCase : () => string + diff --git a/tests/baselines/reference/nullishCoalescingOperator_esnext.js b/tests/baselines/reference/nullishCoalescingOperator_esnext.js new file mode 100644 index 0000000000000..d75fea492c6a8 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator_esnext.js @@ -0,0 +1,62 @@ +//// [nullishCoalescingOperator_esnext.ts] +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null +declare const a7: unknown | null +declare const a8: never | null +declare const a9: any | null + + +const aa1 = a1 ?? 'whatever' +const aa2 = a2 ?? 'whatever' +const aa3 = a3 ?? 'whatever' +const aa4 = a4 ?? 'whatever' +const aa5 = a5 ?? 'whatever' +const aa6 = a6 ?? 'whatever' +const aa7 = a7 ?? 'whatever' +const aa8 = a8 ?? 'whatever' +const aa9 = a9 ?? 'whatever' + + +declare let a: any, b: any, c: any; + +let x1 = (a ?? b as any) || c; +let x2 = c || (a ?? b as any); +let x3 = ((a ?? b) as any) || c; +let x4 = c || ((a ?? b) as any); +let x5 = (a ?? b) as any || c; +let x6 = c || (a ?? b) as any; + +let y1 = (a ?? b as any) && c; +let y2 = c && (a ?? b as any); +let y3 = ((a ?? b) as any) && c; +let y4 = c && ((a ?? b) as any); +let y5 = (a ?? b) as any && c; +let y6 = c && (a ?? b) as any; + +//// [nullishCoalescingOperator_esnext.js] +"use strict"; +const aa1 = a1 ?? 'whatever'; +const aa2 = a2 ?? 'whatever'; +const aa3 = a3 ?? 'whatever'; +const aa4 = a4 ?? 'whatever'; +const aa5 = a5 ?? 'whatever'; +const aa6 = a6 ?? 'whatever'; +const aa7 = a7 ?? 'whatever'; +const aa8 = a8 ?? 'whatever'; +const aa9 = a9 ?? 'whatever'; +let x1 = (a ?? b) || c; +let x2 = c || (a ?? b); +let x3 = (a ?? b) || c; +let x4 = c || (a ?? b); +let x5 = (a ?? b) || c; +let x6 = c || (a ?? b); +let y1 = (a ?? b) && c; +let y2 = c && (a ?? b); +let y3 = (a ?? b) && c; +let y4 = c && (a ?? b); +let y5 = (a ?? b) && c; +let y6 = c && (a ?? b); diff --git a/tests/baselines/reference/nullishCoalescingOperator_esnext.symbols b/tests/baselines/reference/nullishCoalescingOperator_esnext.symbols new file mode 100644 index 0000000000000..42c382c9f1037 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator_esnext.symbols @@ -0,0 +1,143 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_esnext.ts === +declare const a1: 'literal' | undefined | null +>a1 : Symbol(a1, Decl(nullishCoalescingOperator_esnext.ts, 0, 13)) + +declare const a2: '' | undefined | null +>a2 : Symbol(a2, Decl(nullishCoalescingOperator_esnext.ts, 1, 13)) + +declare const a3: 1 | undefined | null +>a3 : Symbol(a3, Decl(nullishCoalescingOperator_esnext.ts, 2, 13)) + +declare const a4: 0 | undefined | null +>a4 : Symbol(a4, Decl(nullishCoalescingOperator_esnext.ts, 3, 13)) + +declare const a5: true | undefined | null +>a5 : Symbol(a5, Decl(nullishCoalescingOperator_esnext.ts, 4, 13)) + +declare const a6: false | undefined | null +>a6 : Symbol(a6, Decl(nullishCoalescingOperator_esnext.ts, 5, 13)) + +declare const a7: unknown | null +>a7 : Symbol(a7, Decl(nullishCoalescingOperator_esnext.ts, 6, 13)) + +declare const a8: never | null +>a8 : Symbol(a8, Decl(nullishCoalescingOperator_esnext.ts, 7, 13)) + +declare const a9: any | null +>a9 : Symbol(a9, Decl(nullishCoalescingOperator_esnext.ts, 8, 13)) + + +const aa1 = a1 ?? 'whatever' +>aa1 : Symbol(aa1, Decl(nullishCoalescingOperator_esnext.ts, 11, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator_esnext.ts, 0, 13)) + +const aa2 = a2 ?? 'whatever' +>aa2 : Symbol(aa2, Decl(nullishCoalescingOperator_esnext.ts, 12, 5)) +>a2 : Symbol(a2, Decl(nullishCoalescingOperator_esnext.ts, 1, 13)) + +const aa3 = a3 ?? 'whatever' +>aa3 : Symbol(aa3, Decl(nullishCoalescingOperator_esnext.ts, 13, 5)) +>a3 : Symbol(a3, Decl(nullishCoalescingOperator_esnext.ts, 2, 13)) + +const aa4 = a4 ?? 'whatever' +>aa4 : Symbol(aa4, Decl(nullishCoalescingOperator_esnext.ts, 14, 5)) +>a4 : Symbol(a4, Decl(nullishCoalescingOperator_esnext.ts, 3, 13)) + +const aa5 = a5 ?? 'whatever' +>aa5 : Symbol(aa5, Decl(nullishCoalescingOperator_esnext.ts, 15, 5)) +>a5 : Symbol(a5, Decl(nullishCoalescingOperator_esnext.ts, 4, 13)) + +const aa6 = a6 ?? 'whatever' +>aa6 : Symbol(aa6, Decl(nullishCoalescingOperator_esnext.ts, 16, 5)) +>a6 : Symbol(a6, Decl(nullishCoalescingOperator_esnext.ts, 5, 13)) + +const aa7 = a7 ?? 'whatever' +>aa7 : Symbol(aa7, Decl(nullishCoalescingOperator_esnext.ts, 17, 5)) +>a7 : Symbol(a7, Decl(nullishCoalescingOperator_esnext.ts, 6, 13)) + +const aa8 = a8 ?? 'whatever' +>aa8 : Symbol(aa8, Decl(nullishCoalescingOperator_esnext.ts, 18, 5)) +>a8 : Symbol(a8, Decl(nullishCoalescingOperator_esnext.ts, 7, 13)) + +const aa9 = a9 ?? 'whatever' +>aa9 : Symbol(aa9, Decl(nullishCoalescingOperator_esnext.ts, 19, 5)) +>a9 : Symbol(a9, Decl(nullishCoalescingOperator_esnext.ts, 8, 13)) + + +declare let a: any, b: any, c: any; +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let x1 = (a ?? b as any) || c; +>x1 : Symbol(x1, Decl(nullishCoalescingOperator_esnext.ts, 24, 3)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let x2 = c || (a ?? b as any); +>x2 : Symbol(x2, Decl(nullishCoalescingOperator_esnext.ts, 25, 3)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) + +let x3 = ((a ?? b) as any) || c; +>x3 : Symbol(x3, Decl(nullishCoalescingOperator_esnext.ts, 26, 3)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let x4 = c || ((a ?? b) as any); +>x4 : Symbol(x4, Decl(nullishCoalescingOperator_esnext.ts, 27, 3)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) + +let x5 = (a ?? b) as any || c; +>x5 : Symbol(x5, Decl(nullishCoalescingOperator_esnext.ts, 28, 3)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let x6 = c || (a ?? b) as any; +>x6 : Symbol(x6, Decl(nullishCoalescingOperator_esnext.ts, 29, 3)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) + +let y1 = (a ?? b as any) && c; +>y1 : Symbol(y1, Decl(nullishCoalescingOperator_esnext.ts, 31, 3)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let y2 = c && (a ?? b as any); +>y2 : Symbol(y2, Decl(nullishCoalescingOperator_esnext.ts, 32, 3)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) + +let y3 = ((a ?? b) as any) && c; +>y3 : Symbol(y3, Decl(nullishCoalescingOperator_esnext.ts, 33, 3)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let y4 = c && ((a ?? b) as any); +>y4 : Symbol(y4, Decl(nullishCoalescingOperator_esnext.ts, 34, 3)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) + +let y5 = (a ?? b) as any && c; +>y5 : Symbol(y5, Decl(nullishCoalescingOperator_esnext.ts, 35, 3)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) + +let y6 = c && (a ?? b) as any; +>y6 : Symbol(y6, Decl(nullishCoalescingOperator_esnext.ts, 36, 3)) +>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27)) +>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11)) +>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator_esnext.types b/tests/baselines/reference/nullishCoalescingOperator_esnext.types new file mode 100644 index 0000000000000..3de2d2c6b4d43 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator_esnext.types @@ -0,0 +1,224 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_esnext.ts === +declare const a1: 'literal' | undefined | null +>a1 : "literal" | null | undefined +>null : null + +declare const a2: '' | undefined | null +>a2 : "" | null | undefined +>null : null + +declare const a3: 1 | undefined | null +>a3 : 1 | null | undefined +>null : null + +declare const a4: 0 | undefined | null +>a4 : 0 | null | undefined +>null : null + +declare const a5: true | undefined | null +>a5 : true | null | undefined +>true : true +>null : null + +declare const a6: false | undefined | null +>a6 : false | null | undefined +>false : false +>null : null + +declare const a7: unknown | null +>a7 : unknown +>null : null + +declare const a8: never | null +>a8 : null +>null : null + +declare const a9: any | null +>a9 : any +>null : null + + +const aa1 = a1 ?? 'whatever' +>aa1 : "literal" | "whatever" +>a1 ?? 'whatever' : "literal" | "whatever" +>a1 : "literal" | null | undefined +>'whatever' : "whatever" + +const aa2 = a2 ?? 'whatever' +>aa2 : "" | "whatever" +>a2 ?? 'whatever' : "" | "whatever" +>a2 : "" | null | undefined +>'whatever' : "whatever" + +const aa3 = a3 ?? 'whatever' +>aa3 : 1 | "whatever" +>a3 ?? 'whatever' : 1 | "whatever" +>a3 : 1 | null | undefined +>'whatever' : "whatever" + +const aa4 = a4 ?? 'whatever' +>aa4 : 0 | "whatever" +>a4 ?? 'whatever' : 0 | "whatever" +>a4 : 0 | null | undefined +>'whatever' : "whatever" + +const aa5 = a5 ?? 'whatever' +>aa5 : true | "whatever" +>a5 ?? 'whatever' : true | "whatever" +>a5 : true | null | undefined +>'whatever' : "whatever" + +const aa6 = a6 ?? 'whatever' +>aa6 : false | "whatever" +>a6 ?? 'whatever' : false | "whatever" +>a6 : false | null | undefined +>'whatever' : "whatever" + +const aa7 = a7 ?? 'whatever' +>aa7 : unknown +>a7 ?? 'whatever' : unknown +>a7 : unknown +>'whatever' : "whatever" + +const aa8 = a8 ?? 'whatever' +>aa8 : "whatever" +>a8 ?? 'whatever' : "whatever" +>a8 : null +>'whatever' : "whatever" + +const aa9 = a9 ?? 'whatever' +>aa9 : any +>a9 ?? 'whatever' : any +>a9 : any +>'whatever' : "whatever" + + +declare let a: any, b: any, c: any; +>a : any +>b : any +>c : any + +let x1 = (a ?? b as any) || c; +>x1 : any +>(a ?? b as any) || c : any +>(a ?? b as any) : any +>a ?? b as any : any +>a : any +>b as any : any +>b : any +>c : any + +let x2 = c || (a ?? b as any); +>x2 : any +>c || (a ?? b as any) : any +>c : any +>(a ?? b as any) : any +>a ?? b as any : any +>a : any +>b as any : any +>b : any + +let x3 = ((a ?? b) as any) || c; +>x3 : any +>((a ?? b) as any) || c : any +>((a ?? b) as any) : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any +>c : any + +let x4 = c || ((a ?? b) as any); +>x4 : any +>c || ((a ?? b) as any) : any +>c : any +>((a ?? b) as any) : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any + +let x5 = (a ?? b) as any || c; +>x5 : any +>(a ?? b) as any || c : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any +>c : any + +let x6 = c || (a ?? b) as any; +>x6 : any +>c || (a ?? b) as any : any +>c : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any + +let y1 = (a ?? b as any) && c; +>y1 : any +>(a ?? b as any) && c : any +>(a ?? b as any) : any +>a ?? b as any : any +>a : any +>b as any : any +>b : any +>c : any + +let y2 = c && (a ?? b as any); +>y2 : any +>c && (a ?? b as any) : any +>c : any +>(a ?? b as any) : any +>a ?? b as any : any +>a : any +>b as any : any +>b : any + +let y3 = ((a ?? b) as any) && c; +>y3 : any +>((a ?? b) as any) && c : any +>((a ?? b) as any) : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any +>c : any + +let y4 = c && ((a ?? b) as any); +>y4 : any +>c && ((a ?? b) as any) : any +>c : any +>((a ?? b) as any) : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any + +let y5 = (a ?? b) as any && c; +>y5 : any +>(a ?? b) as any && c : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any +>c : any + +let y6 = c && (a ?? b) as any; +>y6 : any +>c && (a ?? b) as any : any +>c : any +>(a ?? b) as any : any +>(a ?? b) : any +>a ?? b : any +>a : any +>b : any + diff --git a/tests/baselines/reference/nullishCoalescingOperator_not_strict.js b/tests/baselines/reference/nullishCoalescingOperator_not_strict.js new file mode 100644 index 0000000000000..e8e6d41291ded --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator_not_strict.js @@ -0,0 +1,32 @@ +//// [nullishCoalescingOperator_not_strict.ts] +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null +declare const a7: unknown | null +declare const a8: never | null +declare const a9: any | null + + +const aa1 = a1 ?? 'whatever' +const aa2 = a2 ?? 'whatever' +const aa3 = a3 ?? 'whatever' +const aa4 = a4 ?? 'whatever' +const aa5 = a5 ?? 'whatever' +const aa6 = a6 ?? 'whatever' +const aa7 = a7 ?? 'whatever' +const aa8 = a8 ?? 'whatever' +const aa9 = a9 ?? 'whatever' + +//// [nullishCoalescingOperator_not_strict.js] +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'); +var aa4 = (a4 !== null && a4 !== void 0 ? a4 : 'whatever'); +var aa5 = (a5 !== null && a5 !== void 0 ? a5 : 'whatever'); +var aa6 = (a6 !== null && a6 !== void 0 ? a6 : 'whatever'); +var aa7 = (a7 !== null && a7 !== void 0 ? a7 : 'whatever'); +var aa8 = (a8 !== null && a8 !== void 0 ? a8 : 'whatever'); +var aa9 = (a9 !== null && a9 !== void 0 ? a9 : 'whatever'); diff --git a/tests/baselines/reference/nullishCoalescingOperator_not_strict.symbols b/tests/baselines/reference/nullishCoalescingOperator_not_strict.symbols new file mode 100644 index 0000000000000..76f098e1c2abc --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator_not_strict.symbols @@ -0,0 +1,65 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_not_strict.ts === +declare const a1: 'literal' | undefined | null +>a1 : Symbol(a1, Decl(nullishCoalescingOperator_not_strict.ts, 0, 13)) + +declare const a2: '' | undefined | null +>a2 : Symbol(a2, Decl(nullishCoalescingOperator_not_strict.ts, 1, 13)) + +declare const a3: 1 | undefined | null +>a3 : Symbol(a3, Decl(nullishCoalescingOperator_not_strict.ts, 2, 13)) + +declare const a4: 0 | undefined | null +>a4 : Symbol(a4, Decl(nullishCoalescingOperator_not_strict.ts, 3, 13)) + +declare const a5: true | undefined | null +>a5 : Symbol(a5, Decl(nullishCoalescingOperator_not_strict.ts, 4, 13)) + +declare const a6: false | undefined | null +>a6 : Symbol(a6, Decl(nullishCoalescingOperator_not_strict.ts, 5, 13)) + +declare const a7: unknown | null +>a7 : Symbol(a7, Decl(nullishCoalescingOperator_not_strict.ts, 6, 13)) + +declare const a8: never | null +>a8 : Symbol(a8, Decl(nullishCoalescingOperator_not_strict.ts, 7, 13)) + +declare const a9: any | null +>a9 : Symbol(a9, Decl(nullishCoalescingOperator_not_strict.ts, 8, 13)) + + +const aa1 = a1 ?? 'whatever' +>aa1 : Symbol(aa1, Decl(nullishCoalescingOperator_not_strict.ts, 11, 5)) +>a1 : Symbol(a1, Decl(nullishCoalescingOperator_not_strict.ts, 0, 13)) + +const aa2 = a2 ?? 'whatever' +>aa2 : Symbol(aa2, Decl(nullishCoalescingOperator_not_strict.ts, 12, 5)) +>a2 : Symbol(a2, Decl(nullishCoalescingOperator_not_strict.ts, 1, 13)) + +const aa3 = a3 ?? 'whatever' +>aa3 : Symbol(aa3, Decl(nullishCoalescingOperator_not_strict.ts, 13, 5)) +>a3 : Symbol(a3, Decl(nullishCoalescingOperator_not_strict.ts, 2, 13)) + +const aa4 = a4 ?? 'whatever' +>aa4 : Symbol(aa4, Decl(nullishCoalescingOperator_not_strict.ts, 14, 5)) +>a4 : Symbol(a4, Decl(nullishCoalescingOperator_not_strict.ts, 3, 13)) + +const aa5 = a5 ?? 'whatever' +>aa5 : Symbol(aa5, Decl(nullishCoalescingOperator_not_strict.ts, 15, 5)) +>a5 : Symbol(a5, Decl(nullishCoalescingOperator_not_strict.ts, 4, 13)) + +const aa6 = a6 ?? 'whatever' +>aa6 : Symbol(aa6, Decl(nullishCoalescingOperator_not_strict.ts, 16, 5)) +>a6 : Symbol(a6, Decl(nullishCoalescingOperator_not_strict.ts, 5, 13)) + +const aa7 = a7 ?? 'whatever' +>aa7 : Symbol(aa7, Decl(nullishCoalescingOperator_not_strict.ts, 17, 5)) +>a7 : Symbol(a7, Decl(nullishCoalescingOperator_not_strict.ts, 6, 13)) + +const aa8 = a8 ?? 'whatever' +>aa8 : Symbol(aa8, Decl(nullishCoalescingOperator_not_strict.ts, 18, 5)) +>a8 : Symbol(a8, Decl(nullishCoalescingOperator_not_strict.ts, 7, 13)) + +const aa9 = a9 ?? 'whatever' +>aa9 : Symbol(aa9, Decl(nullishCoalescingOperator_not_strict.ts, 19, 5)) +>a9 : Symbol(a9, Decl(nullishCoalescingOperator_not_strict.ts, 8, 13)) + diff --git a/tests/baselines/reference/nullishCoalescingOperator_not_strict.types b/tests/baselines/reference/nullishCoalescingOperator_not_strict.types new file mode 100644 index 0000000000000..adfdce759dce5 --- /dev/null +++ b/tests/baselines/reference/nullishCoalescingOperator_not_strict.types @@ -0,0 +1,94 @@ +=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_not_strict.ts === +declare const a1: 'literal' | undefined | null +>a1 : "literal" +>null : null + +declare const a2: '' | undefined | null +>a2 : "" +>null : null + +declare const a3: 1 | undefined | null +>a3 : 1 +>null : null + +declare const a4: 0 | undefined | null +>a4 : 0 +>null : null + +declare const a5: true | undefined | null +>a5 : true +>true : true +>null : null + +declare const a6: false | undefined | null +>a6 : false +>false : false +>null : null + +declare const a7: unknown | null +>a7 : unknown +>null : null + +declare const a8: never | null +>a8 : null +>null : null + +declare const a9: any | null +>a9 : any +>null : null + + +const aa1 = a1 ?? 'whatever' +>aa1 : "literal" | "whatever" +>a1 ?? 'whatever' : "literal" | "whatever" +>a1 : "literal" +>'whatever' : "whatever" + +const aa2 = a2 ?? 'whatever' +>aa2 : "" | "whatever" +>a2 ?? 'whatever' : "" | "whatever" +>a2 : "" +>'whatever' : "whatever" + +const aa3 = a3 ?? 'whatever' +>aa3 : 1 | "whatever" +>a3 ?? 'whatever' : 1 | "whatever" +>a3 : 1 +>'whatever' : "whatever" + +const aa4 = a4 ?? 'whatever' +>aa4 : 0 | "whatever" +>a4 ?? 'whatever' : 0 | "whatever" +>a4 : 0 +>'whatever' : "whatever" + +const aa5 = a5 ?? 'whatever' +>aa5 : true | "whatever" +>a5 ?? 'whatever' : true | "whatever" +>a5 : true +>'whatever' : "whatever" + +const aa6 = a6 ?? 'whatever' +>aa6 : false | "whatever" +>a6 ?? 'whatever' : false | "whatever" +>a6 : false +>'whatever' : "whatever" + +const aa7 = a7 ?? 'whatever' +>aa7 : unknown +>a7 ?? 'whatever' : unknown +>a7 : unknown +>'whatever' : "whatever" + +const aa8 = a8 ?? 'whatever' +>aa8 : "whatever" +>a8 ?? 'whatever' : "whatever" +>a8 : null +>'whatever' : "whatever" + +const aa9 = a9 ?? 'whatever' +>aa9 : any +>a9 ?? 'whatever' : any +>a9 : any +>'whatever' : "whatever" + diff --git a/tests/baselines/reference/typeFromPropertyAssignment10_1.symbols b/tests/baselines/reference/typeFromPropertyAssignment10_1.symbols new file mode 100644 index 0000000000000..9f0d484d8f40a --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment10_1.symbols @@ -0,0 +1,141 @@ +=== tests/cases/conformance/salsa/module.js === +var Outer = Outer ?? {}; +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) + +Outer.app = Outer.app ?? {}; +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) + +=== tests/cases/conformance/salsa/someview.js === +Outer.app.SomeView = (function () { +>Outer.app.SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) + + var SomeView = function() { +>SomeView : Symbol(SomeView, Decl(someview.js, 1, 7)) + + var me = this; +>me : Symbol(me, Decl(someview.js, 2, 11)) + } + return SomeView; +>SomeView : Symbol(SomeView, Decl(someview.js, 1, 7)) + +})(); +Outer.app.Inner = class { +>Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) + + constructor() { + /** @type {number} */ + this.y = 12; +>this.y : Symbol(Inner.y, Decl(someview.js, 7, 19)) +>this : Symbol(Inner, Decl(someview.js, 6, 17)) +>y : Symbol(Inner.y, Decl(someview.js, 7, 19)) + } +} +var example = new Outer.app.Inner(); +>example : Symbol(example, Decl(someview.js, 12, 3)) +>Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) + +example.y; +>example.y : Symbol(Inner.y, Decl(someview.js, 7, 19)) +>example : Symbol(example, Decl(someview.js, 12, 3)) +>y : Symbol(Inner.y, Decl(someview.js, 7, 19)) + +/** @param {number} k */ +Outer.app.statische = function (k) { +>Outer.app.statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) +>k : Symbol(k, Decl(someview.js, 15, 32)) + + return k ** k; +>k : Symbol(k, Decl(someview.js, 15, 32)) +>k : Symbol(k, Decl(someview.js, 15, 32)) +} +=== tests/cases/conformance/salsa/application.js === +Outer.app.Application = (function () { +>Outer.app.Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) + + /** + * Application main class. + * Will be instantiated & initialized by HTML page + */ + var Application = function () { +>Application : Symbol(Application, Decl(application.js, 6, 7)) + + var me = this; +>me : Symbol(me, Decl(application.js, 7, 11)) + + me.view = new Outer.app.SomeView(); +>me : Symbol(me, Decl(application.js, 7, 11)) +>Outer.app.SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) + + }; + return Application; +>Application : Symbol(Application, Decl(application.js, 6, 7)) + +})(); +=== tests/cases/conformance/salsa/main.js === +var app = new Outer.app.Application(); +>app : Symbol(app, Decl(main.js, 0, 3)) +>Outer.app.Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) + +var inner = new Outer.app.Inner(); +>inner : Symbol(inner, Decl(main.js, 1, 3)) +>Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) + +inner.y; +>inner.y : Symbol(Inner.y, Decl(someview.js, 7, 19)) +>inner : Symbol(inner, Decl(main.js, 1, 3)) +>y : Symbol(Inner.y, Decl(someview.js, 7, 19)) + +/** @type {Outer.app.Inner} */ +var x; +>x : Symbol(x, Decl(main.js, 4, 3)) + +x.y; +>x.y : Symbol(Inner.y, Decl(someview.js, 7, 19)) +>x : Symbol(x, Decl(main.js, 4, 3)) +>y : Symbol(Inner.y, Decl(someview.js, 7, 19)) + +Outer.app.statische(101); // Infinity, duh +>Outer.app.statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(someview.js, 5, 5), Decl(someview.js, 13, 10) ... and 1 more) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(someview.js, 6, 6), Decl(someview.js, 15, 6), Decl(application.js, 0, 6)) +>statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment10_1.types b/tests/baselines/reference/typeFromPropertyAssignment10_1.types new file mode 100644 index 0000000000000..fa593e6dacfae --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment10_1.types @@ -0,0 +1,174 @@ +=== tests/cases/conformance/salsa/module.js === +var Outer = Outer ?? {}; +>Outer : typeof Outer +>Outer ?? {} : typeof Outer | {} +>Outer : typeof Outer +>{} : {} + +Outer.app = Outer.app ?? {}; +>Outer.app = Outer.app ?? {} : typeof Outer.app +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>Outer.app ?? {} : {} +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>{} : {} + +=== tests/cases/conformance/salsa/someview.js === +Outer.app.SomeView = (function () { +>Outer.app.SomeView = (function () { var SomeView = function() { var me = this; } return SomeView;})() : () => void +>Outer.app.SomeView : () => void +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>SomeView : () => void +>(function () { var SomeView = function() { var me = this; } return SomeView;})() : () => void +>(function () { var SomeView = function() { var me = this; } return SomeView;}) : () => () => void +>function () { var SomeView = function() { var me = this; } return SomeView;} : () => () => void + + var SomeView = function() { +>SomeView : () => void +>function() { var me = this; } : () => void + + var me = this; +>me : any +>this : any + } + return SomeView; +>SomeView : () => void + +})(); +Outer.app.Inner = class { +>Outer.app.Inner = class { constructor() { /** @type {number} */ this.y = 12; }} : typeof Inner +>Outer.app.Inner : typeof Inner +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>Inner : typeof Inner +>class { constructor() { /** @type {number} */ this.y = 12; }} : typeof Inner + + constructor() { + /** @type {number} */ + this.y = 12; +>this.y = 12 : 12 +>this.y : number +>this : this +>y : number +>12 : 12 + } +} +var example = new Outer.app.Inner(); +>example : Inner +>new Outer.app.Inner() : Inner +>Outer.app.Inner : typeof Inner +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>Inner : typeof Inner + +example.y; +>example.y : number +>example : Inner +>y : number + +/** @param {number} k */ +Outer.app.statische = function (k) { +>Outer.app.statische = function (k) { return k ** k;} : (k: number) => number +>Outer.app.statische : (k: number) => number +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>statische : (k: number) => number +>function (k) { return k ** k;} : (k: number) => number +>k : number + + return k ** k; +>k ** k : number +>k : number +>k : number +} +=== tests/cases/conformance/salsa/application.js === +Outer.app.Application = (function () { +>Outer.app.Application = (function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;})() : () => void +>Outer.app.Application : () => void +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>Application : () => void +>(function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;})() : () => void +>(function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;}) : () => () => void +>function () { /** * Application main class. * Will be instantiated & initialized by HTML page */ var Application = function () { var me = this; me.view = new Outer.app.SomeView(); }; return Application;} : () => () => void + + /** + * Application main class. + * Will be instantiated & initialized by HTML page + */ + var Application = function () { +>Application : () => void +>function () { var me = this; me.view = new Outer.app.SomeView(); } : () => void + + var me = this; +>me : any +>this : any + + me.view = new Outer.app.SomeView(); +>me.view = new Outer.app.SomeView() : any +>me.view : any +>me : any +>view : any +>new Outer.app.SomeView() : any +>Outer.app.SomeView : () => void +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>SomeView : () => void + + }; + return Application; +>Application : () => void + +})(); +=== tests/cases/conformance/salsa/main.js === +var app = new Outer.app.Application(); +>app : any +>new Outer.app.Application() : any +>Outer.app.Application : () => void +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>Application : () => void + +var inner = new Outer.app.Inner(); +>inner : Inner +>new Outer.app.Inner() : Inner +>Outer.app.Inner : typeof Inner +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>Inner : typeof Inner + +inner.y; +>inner.y : number +>inner : Inner +>y : number + +/** @type {Outer.app.Inner} */ +var x; +>x : Inner + +x.y; +>x.y : number +>x : Inner +>y : number + +Outer.app.statische(101); // Infinity, duh +>Outer.app.statische(101) : number +>Outer.app.statische : (k: number) => number +>Outer.app : typeof Outer.app +>Outer : typeof Outer +>app : typeof Outer.app +>statische : (k: number) => number +>101 : 101 + diff --git a/tests/baselines/reference/typeFromPropertyAssignment8_1.symbols b/tests/baselines/reference/typeFromPropertyAssignment8_1.symbols new file mode 100644 index 0000000000000..21054155016bc --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment8_1.symbols @@ -0,0 +1,74 @@ +=== tests/cases/conformance/salsa/a.js === +var my = my ?? {}; +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) + +my.app = my.app ?? {}; +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) + +my.app.Application = (function () { +>my.app.Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) + +var Application = function () { +>Application : Symbol(Application, Decl(a.js, 4, 3)) + + //... +}; +return Application; +>Application : Symbol(Application, Decl(a.js, 4, 3)) + +})(); +my.app.Application() +>my.app.Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) + +=== tests/cases/conformance/salsa/b.js === +var min = window.min ?? {}; +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) +>window.min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) + +min.app = min.app ?? {}; +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) + +min.app.Application = (function () { +>min.app.Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) + +var Application = function () { +>Application : Symbol(Application, Decl(b.js, 4, 3)) + + //... +}; +return Application; +>Application : Symbol(Application, Decl(b.js, 4, 3)) + +})(); +min.app.Application() +>min.app.Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment8_1.types b/tests/baselines/reference/typeFromPropertyAssignment8_1.types new file mode 100644 index 0000000000000..fd30f6168b657 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment8_1.types @@ -0,0 +1,96 @@ +=== tests/cases/conformance/salsa/a.js === +var my = my ?? {}; +>my : typeof my +>my ?? {} : typeof my | {} +>my : typeof my +>{} : {} + +my.app = my.app ?? {}; +>my.app = my.app ?? {} : typeof my.app +>my.app : typeof my.app +>my : typeof my +>app : typeof my.app +>my.app ?? {} : {} +>my.app : typeof my.app +>my : typeof my +>app : typeof my.app +>{} : {} + +my.app.Application = (function () { +>my.app.Application = (function () {var Application = function () { //...};return Application;})() : () => void +>my.app.Application : () => void +>my.app : typeof my.app +>my : typeof my +>app : typeof my.app +>Application : () => void +>(function () {var Application = function () { //...};return Application;})() : () => void +>(function () {var Application = function () { //...};return Application;}) : () => () => void +>function () {var Application = function () { //...};return Application;} : () => () => void + +var Application = function () { +>Application : () => void +>function () { //...} : () => void + + //... +}; +return Application; +>Application : () => void + +})(); +my.app.Application() +>my.app.Application() : void +>my.app.Application : () => void +>my.app : typeof my.app +>my : typeof my +>app : typeof my.app +>Application : () => void + +=== tests/cases/conformance/salsa/b.js === +var min = window.min ?? {}; +>min : typeof min +>window.min ?? {} : typeof min | {} +>window.min : typeof min +>window : Window & typeof globalThis +>min : typeof min +>{} : {} + +min.app = min.app ?? {}; +>min.app = min.app ?? {} : typeof min.app +>min.app : typeof min.app +>min : typeof min +>app : typeof min.app +>min.app ?? {} : {} +>min.app : typeof min.app +>min : typeof min +>app : typeof min.app +>{} : {} + +min.app.Application = (function () { +>min.app.Application = (function () {var Application = function () { //...};return Application;})() : () => void +>min.app.Application : () => void +>min.app : typeof min.app +>min : typeof min +>app : typeof min.app +>Application : () => void +>(function () {var Application = function () { //...};return Application;})() : () => void +>(function () {var Application = function () { //...};return Application;}) : () => () => void +>function () {var Application = function () { //...};return Application;} : () => () => void + +var Application = function () { +>Application : () => void +>function () { //...} : () => void + + //... +}; +return Application; +>Application : () => void + +})(); +min.app.Application() +>min.app.Application() : void +>min.app.Application : () => void +>min.app : typeof min.app +>min : typeof min +>app : typeof min.app +>Application : () => void + diff --git a/tests/baselines/reference/typeFromPropertyAssignment9_1.symbols b/tests/baselines/reference/typeFromPropertyAssignment9_1.symbols new file mode 100644 index 0000000000000..bd81d2cf9ab62 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment9_1.symbols @@ -0,0 +1,147 @@ +=== tests/cases/conformance/salsa/a.js === +var my = my ?? {}; +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) + +/** @param {number} n */ +my.method = function(n) { +>my.method : Symbol(my.method, Decl(a.js, 0, 18)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>method : Symbol(my.method, Decl(a.js, 0, 18)) +>n : Symbol(n, Decl(a.js, 2, 21)) + + return n + 1; +>n : Symbol(n, Decl(a.js, 2, 21)) +} +my.number = 1; +>my.number : Symbol(my.number, Decl(a.js, 4, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>number : Symbol(my.number, Decl(a.js, 4, 1)) + +my.object = {}; +>my.object : Symbol(my.object, Decl(a.js, 5, 14)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>object : Symbol(my.object, Decl(a.js, 5, 14)) + +my.predicate = my.predicate ?? {}; +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) + +my.predicate.query = function () { +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) + + var me = this; +>me : Symbol(me, Decl(a.js, 9, 7)) +>this : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) + + me.property = false; +>me : Symbol(me, Decl(a.js, 9, 7)) + +}; +var q = new my.predicate.query(); +>q : Symbol(q, Decl(a.js, 12, 3)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) + +my.predicate.query.another = function () { +>my.predicate.query.another : Symbol(my.predicate.query.another, Decl(a.js, 12, 33)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) +>another : Symbol(my.predicate.query.another, Decl(a.js, 12, 33)) + + return 1; +} +my.predicate.query.result = 'none' +>my.predicate.query.result : Symbol(my.predicate.query.result, Decl(a.js, 15, 1)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13), Decl(a.js, 16, 13)) +>result : Symbol(my.predicate.query.result, Decl(a.js, 15, 1)) + +/** @param {number} first + * @param {number} second + */ +my.predicate.sort = my.predicate.sort ?? function (first, second) { +>my.predicate.sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>my.predicate.sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>first : Symbol(first, Decl(a.js, 20, 51)) +>second : Symbol(second, Decl(a.js, 20, 57)) + + return first > second ? first : second; +>first : Symbol(first, Decl(a.js, 20, 51)) +>second : Symbol(second, Decl(a.js, 20, 57)) +>first : Symbol(first, Decl(a.js, 20, 51)) +>second : Symbol(second, Decl(a.js, 20, 57)) +} +my.predicate.type = class { +>my.predicate.type : Symbol(my.predicate.type, Decl(a.js, 22, 1)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 4, 1), Decl(a.js, 5, 14), Decl(a.js, 6, 15) ... and 5 more) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 16, 3), Decl(a.js, 20, 3) ... and 1 more) +>type : Symbol(my.predicate.type, Decl(a.js, 22, 1)) + + m() { return 101; } +>m : Symbol(type.m, Decl(a.js, 23, 27)) +} + + +// global-ish prefixes +var min = window.min ?? {}; +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>window.min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) + +min.nest = this.min.nest ?? function () { }; +>min.nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>this.min.nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>this.min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>this : Symbol(globalThis) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) + +min.nest.other = self.min.nest.other ?? class { }; +>min.nest.other : Symbol(min.nest.other, Decl(a.js, 30, 44)) +>min.nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>other : Symbol(min.nest.other, Decl(a.js, 30, 44)) +>self.min.nest.other : Symbol(min.nest.other, Decl(a.js, 30, 44)) +>self.min.nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>self.min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>self : Symbol(self, Decl(lib.dom.d.ts, --, --)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>other : Symbol(min.nest.other, Decl(a.js, 30, 44)) + +min.property = global.min.property ?? {}; +>min.property : Symbol(min.property, Decl(a.js, 31, 50)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>property : Symbol(min.property, Decl(a.js, 31, 50)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment9_1.types b/tests/baselines/reference/typeFromPropertyAssignment9_1.types new file mode 100644 index 0000000000000..059466c8cfc0c --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment9_1.types @@ -0,0 +1,196 @@ +=== tests/cases/conformance/salsa/a.js === +var my = my ?? {}; +>my : typeof my +>my ?? {} : typeof my | {} +>my : typeof my +>{} : {} + +/** @param {number} n */ +my.method = function(n) { +>my.method = function(n) { return n + 1;} : (n: number) => number +>my.method : (n: number) => number +>my : typeof my +>method : (n: number) => number +>function(n) { return n + 1;} : (n: number) => number +>n : number + + return n + 1; +>n + 1 : number +>n : number +>1 : 1 +} +my.number = 1; +>my.number = 1 : 1 +>my.number : number +>my : typeof my +>number : number +>1 : 1 + +my.object = {}; +>my.object = {} : {} +>my.object : {} +>my : typeof my +>object : {} +>{} : {} + +my.predicate = my.predicate ?? {}; +>my.predicate = my.predicate ?? {} : typeof my.predicate +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>my.predicate ?? {} : {} +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>{} : {} + +my.predicate.query = function () { +>my.predicate.query = function () { var me = this; me.property = false;} : { (): void; another(): number; result: string; } +>my.predicate.query : { (): void; another(): number; result: string; } +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>query : { (): void; another(): number; result: string; } +>function () { var me = this; me.property = false;} : { (): void; another(): number; result: string; } + + var me = this; +>me : typeof my.predicate +>this : typeof my.predicate + + me.property = false; +>me.property = false : false +>me.property : any +>me : typeof my.predicate +>property : any +>false : false + +}; +var q = new my.predicate.query(); +>q : any +>new my.predicate.query() : any +>my.predicate.query : { (): void; another(): number; result: string; } +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>query : { (): void; another(): number; result: string; } + +my.predicate.query.another = function () { +>my.predicate.query.another = function () { return 1;} : () => number +>my.predicate.query.another : () => number +>my.predicate.query : { (): void; another(): number; result: string; } +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>query : { (): void; another(): number; result: string; } +>another : () => number +>function () { return 1;} : () => number + + return 1; +>1 : 1 +} +my.predicate.query.result = 'none' +>my.predicate.query.result = 'none' : "none" +>my.predicate.query.result : string +>my.predicate.query : { (): void; another(): number; result: string; } +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>query : { (): void; another(): number; result: string; } +>result : string +>'none' : "none" + +/** @param {number} first + * @param {number} second + */ +my.predicate.sort = my.predicate.sort ?? function (first, second) { +>my.predicate.sort = my.predicate.sort ?? function (first, second) { return first > second ? first : second;} : (first: number, second: number) => number +>my.predicate.sort : (first: number, second: number) => number +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>sort : (first: number, second: number) => number +>my.predicate.sort ?? function (first, second) { return first > second ? first : second;} : (first: number, second: number) => number +>my.predicate.sort : (first: number, second: number) => number +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>sort : (first: number, second: number) => number +>function (first, second) { return first > second ? first : second;} : (first: number, second: number) => number +>first : number +>second : number + + return first > second ? first : second; +>first > second ? first : second : number +>first > second : boolean +>first : number +>second : number +>first : number +>second : number +} +my.predicate.type = class { +>my.predicate.type = class { m() { return 101; }} : typeof type +>my.predicate.type : typeof type +>my.predicate : typeof my.predicate +>my : typeof my +>predicate : typeof my.predicate +>type : typeof type +>class { m() { return 101; }} : typeof type + + m() { return 101; } +>m : () => number +>101 : 101 +} + + +// global-ish prefixes +var min = window.min ?? {}; +>min : typeof min +>window.min ?? {} : typeof min | {} +>window.min : typeof min +>window : Window & typeof globalThis +>min : typeof min +>{} : {} + +min.nest = this.min.nest ?? function () { }; +>min.nest = this.min.nest ?? function () { } : { (): void; other: typeof other; } +>min.nest : { (): void; other: typeof other; } +>min : typeof min +>nest : { (): void; other: typeof other; } +>this.min.nest ?? function () { } : { (): void; other: typeof other; } +>this.min.nest : { (): void; other: typeof other; } +>this.min : typeof min +>this : typeof globalThis +>min : typeof min +>nest : { (): void; other: typeof other; } +>function () { } : { (): void; other: typeof other; } + +min.nest.other = self.min.nest.other ?? class { }; +>min.nest.other = self.min.nest.other ?? class { } : typeof other +>min.nest.other : typeof other +>min.nest : { (): void; other: typeof other; } +>min : typeof min +>nest : { (): void; other: typeof other; } +>other : typeof other +>self.min.nest.other ?? class { } : typeof other +>self.min.nest.other : typeof other +>self.min.nest : { (): void; other: typeof other; } +>self.min : typeof min +>self : Window & typeof globalThis +>min : typeof min +>nest : { (): void; other: typeof other; } +>other : typeof other +>class { } : typeof other + +min.property = global.min.property ?? {}; +>min.property = global.min.property ?? {} : {} +>min.property : {} +>min : typeof min +>property : {} +>global.min.property ?? {} : {} +>global.min.property : error +>global.min : any +>global : any +>min : any +>property : any +>{} : {} + diff --git a/tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts b/tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts new file mode 100644 index 0000000000000..2e5a8ea1a60fe --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowNullishCoalesce.ts @@ -0,0 +1,14 @@ +// @strict: true + +// assignments in shortcutting rhs +let a: number; +o ?? (a = 1); +a.toString(); + +// assignment flow +declare const o: { x: number } | undefined; +let x: { x: number } | boolean; +if (x = o ?? true) { + x; +} + diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator1.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator1.ts new file mode 100644 index 0000000000000..80f0c64e7d94d --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator1.ts @@ -0,0 +1,42 @@ +// @strict: true + +declare const a1: string | undefined | null +declare const a2: string | undefined | null +declare const a3: string | undefined | null +declare const a4: string | undefined | null + +declare const b1: number | undefined | null +declare const b2: number | undefined | null +declare const b3: number | undefined | null +declare const b4: number | undefined | null + +declare const c1: boolean | undefined | null +declare const c2: boolean | undefined | null +declare const c3: boolean | undefined | null +declare const c4: boolean | undefined | null + +interface I { a: string } +declare const d1: I | undefined | null +declare const d2: I | undefined | null +declare const d3: I | undefined | null +declare const d4: I | undefined | null + +const aa1 = a1 ?? 'whatever'; +const aa2 = a2 ?? 'whatever'; +const aa3 = a3 ?? 'whatever'; +const aa4 = a4 ?? 'whatever'; + +const bb1 = b1 ?? 1; +const bb2 = b2 ?? 1; +const bb3 = b3 ?? 1; +const bb4 = b4 ?? 1; + +const cc1 = c1 ?? true; +const cc2 = c2 ?? true; +const cc3 = c3 ?? true; +const cc4 = c4 ?? true; + +const dd1 = d1 ?? {b: 1}; +const dd2 = d2 ?? {b: 1}; +const dd3 = d3 ?? {b: 1}; +const dd4 = d4 ?? {b: 1}; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator10.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator10.ts new file mode 100644 index 0000000000000..bc86af57a8e8a --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator10.ts @@ -0,0 +1,6 @@ +// @strict: true + +declare function f(): string | undefined; + +let gg = f() ?? 'foo' + diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts new file mode 100644 index 0000000000000..0121ecee890eb --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator11.ts @@ -0,0 +1,7 @@ +// @strict: true + +declare const f11: 1 | 0 | '' | null | undefined; + +let g11 = f11 ?? f11.toFixed() + + diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator2.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator2.ts new file mode 100644 index 0000000000000..5d5761aeec534 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator2.ts @@ -0,0 +1,22 @@ +// @strict: true + +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null +declare const a7: unknown | null +declare const a8: never | null +declare const a9: any | null + + +const aa1 = a1 ?? 'whatever' +const aa2 = a2 ?? 'whatever' +const aa3 = a3 ?? 'whatever' +const aa4 = a4 ?? 'whatever' +const aa5 = a5 ?? 'whatever' +const aa6 = a6 ?? 'whatever' +const aa7 = a7 ?? 'whatever' +const aa8 = a8 ?? 'whatever' +const aa9 = a9 ?? 'whatever' \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator3.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator3.ts new file mode 100644 index 0000000000000..288b7cec4fb70 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator3.ts @@ -0,0 +1,11 @@ +// @strict: true + +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null + + +const aa1 = a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 ?? 'whatever' diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts new file mode 100644 index 0000000000000..96109d8ad1cd1 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator4.ts @@ -0,0 +1,5 @@ +// @strict: true + +declare const a1: 'literal' | undefined | null +const aa1 = a1 ?? a1.toLowerCase() +const aa2 = a1 || a1.toLocaleUpperCase() diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts new file mode 100644 index 0000000000000..d1c68e0dd7775 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator5.ts @@ -0,0 +1,41 @@ +// @strict: true + +declare const a: string | undefined +declare const b: string | undefined +declare const c: string | undefined + +// should be a syntax error +a ?? b || c; + +// should be a syntax error +a || b ?? c; + +// should be a syntax error +a ?? b && c; + +// should be a syntax error +a && b ?? c; + +// Valid according to spec +a ?? (b || c); + +// Valid according to spec +(a ?? b) || c; + +// Valid according to spec +(a || b) ?? c; + +// Valid according to spec +a || (b ?? c); + +// Valid according to spec +a ?? (b && c); + +// Valid according to spec +(a ?? b) && c; + +// Valid according to spec +(a && b) ?? c; + +// Valid according to spec +a && (b ?? c); diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator6.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator6.ts new file mode 100644 index 0000000000000..01db04f4ab269 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator6.ts @@ -0,0 +1,3 @@ +// @strict: true + +function foo(foo: string, bar = foo ?? "bar") { } diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator7.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator7.ts new file mode 100644 index 0000000000000..0390e8ec480e4 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator7.ts @@ -0,0 +1,13 @@ +// @strict: true + +declare const a: string | undefined; +declare const b: string | undefined; +declare const c: string | undefined; + +const foo1 = a ? 1 : 2; +const foo2 = a ?? 'foo' ? 1 : 2; +const foo3 = a ?? 'foo' ? (b ?? 'bar') : (c ?? 'baz'); + +function f () { + const foo4 = a ?? 'foo' ? b ?? 'bar' : c ?? 'baz'; +} diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts new file mode 100644 index 0000000000000..228ea0ecf82ef --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts @@ -0,0 +1,8 @@ +// @strict: true + +declare const a: { p: string | undefined, m(): string | undefined }; +declare const b: { p: string | undefined, m(): string | undefined }; + +const n1 = a.p ?? "default"; +const n2 = a.m() ?? "default"; +const n3 = a.m() ?? b.p ?? b.m() ?? "default";; diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator9.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator9.ts new file mode 100644 index 0000000000000..bd47a0ff7cb63 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator9.ts @@ -0,0 +1,6 @@ +// @strict: true + +declare let f: null | ((x: string) => void); + +let g = f || (abc => { void abc.toLowerCase() }) +let gg = f ?? (abc => { void abc.toLowerCase() }) diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_esnext.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_esnext.ts new file mode 100644 index 0000000000000..c718ca189e70d --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_esnext.ts @@ -0,0 +1,40 @@ +// @strict: true +// @target: esnext + +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null +declare const a7: unknown | null +declare const a8: never | null +declare const a9: any | null + + +const aa1 = a1 ?? 'whatever' +const aa2 = a2 ?? 'whatever' +const aa3 = a3 ?? 'whatever' +const aa4 = a4 ?? 'whatever' +const aa5 = a5 ?? 'whatever' +const aa6 = a6 ?? 'whatever' +const aa7 = a7 ?? 'whatever' +const aa8 = a8 ?? 'whatever' +const aa9 = a9 ?? 'whatever' + + +declare let a: any, b: any, c: any; + +let x1 = (a ?? b as any) || c; +let x2 = c || (a ?? b as any); +let x3 = ((a ?? b) as any) || c; +let x4 = c || ((a ?? b) as any); +let x5 = (a ?? b) as any || c; +let x6 = c || (a ?? b) as any; + +let y1 = (a ?? b as any) && c; +let y2 = c && (a ?? b as any); +let y3 = ((a ?? b) as any) && c; +let y4 = c && ((a ?? b) as any); +let y5 = (a ?? b) as any && c; +let y6 = c && (a ?? b) as any; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_not_strict.ts b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_not_strict.ts new file mode 100644 index 0000000000000..d05e1c6541eb6 --- /dev/null +++ b/tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator_not_strict.ts @@ -0,0 +1,22 @@ +// @strict: false + +declare const a1: 'literal' | undefined | null +declare const a2: '' | undefined | null +declare const a3: 1 | undefined | null +declare const a4: 0 | undefined | null +declare const a5: true | undefined | null +declare const a6: false | undefined | null +declare const a7: unknown | null +declare const a8: never | null +declare const a9: any | null + + +const aa1 = a1 ?? 'whatever' +const aa2 = a2 ?? 'whatever' +const aa3 = a3 ?? 'whatever' +const aa4 = a4 ?? 'whatever' +const aa5 = a5 ?? 'whatever' +const aa6 = a6 ?? 'whatever' +const aa7 = a7 ?? 'whatever' +const aa8 = a8 ?? 'whatever' +const aa9 = a9 ?? 'whatever' \ No newline at end of file diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment10_1.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment10_1.ts new file mode 100644 index 0000000000000..5e5228874d223 --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment10_1.ts @@ -0,0 +1,48 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @target: esnext +// @Filename: module.js +var Outer = Outer ?? {}; +Outer.app = Outer.app ?? {}; + +// @Filename: someview.js +Outer.app.SomeView = (function () { + var SomeView = function() { + var me = this; + } + return SomeView; +})(); +Outer.app.Inner = class { + constructor() { + /** @type {number} */ + this.y = 12; + } +} +var example = new Outer.app.Inner(); +example.y; +/** @param {number} k */ +Outer.app.statische = function (k) { + return k ** k; +} +// @Filename: application.js +Outer.app.Application = (function () { + + /** + * Application main class. + * Will be instantiated & initialized by HTML page + */ + var Application = function () { + var me = this; + me.view = new Outer.app.SomeView(); + }; + return Application; +})(); +// @Filename: main.js +var app = new Outer.app.Application(); +var inner = new Outer.app.Inner(); +inner.y; +/** @type {Outer.app.Inner} */ +var x; +x.y; +Outer.app.statische(101); // Infinity, duh diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment8_1.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment8_1.ts new file mode 100644 index 0000000000000..2d6040e319dba --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment8_1.ts @@ -0,0 +1,28 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @target: esnext +// @lib: es6,dom +// @Filename: a.js +var my = my ?? {}; +my.app = my.app ?? {}; + +my.app.Application = (function () { +var Application = function () { + //... +}; +return Application; +})(); +my.app.Application() + +// @Filename: b.js +var min = window.min ?? {}; +min.app = min.app ?? {}; + +min.app.Application = (function () { +var Application = function () { + //... +}; +return Application; +})(); +min.app.Application() diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment9_1.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment9_1.ts new file mode 100644 index 0000000000000..61f6de98abbae --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment9_1.ts @@ -0,0 +1,39 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @target: esnext +// @Filename: a.js + +var my = my ?? {}; +/** @param {number} n */ +my.method = function(n) { + return n + 1; +} +my.number = 1; +my.object = {}; +my.predicate = my.predicate ?? {}; +my.predicate.query = function () { + var me = this; + me.property = false; +}; +var q = new my.predicate.query(); +my.predicate.query.another = function () { + return 1; +} +my.predicate.query.result = 'none' +/** @param {number} first + * @param {number} second + */ +my.predicate.sort = my.predicate.sort ?? function (first, second) { + return first > second ? first : second; +} +my.predicate.type = class { + m() { return 101; } +} + + +// global-ish prefixes +var min = window.min ?? {}; +min.nest = this.min.nest ?? function () { }; +min.nest.other = self.min.nest.other ?? class { }; +min.property = global.min.property ?? {}; diff --git a/tests/cases/fourslash/codefixInferFromUsageNullish.ts b/tests/cases/fourslash/codefixInferFromUsageNullish.ts new file mode 100644 index 0000000000000..d1073a9d9a958 --- /dev/null +++ b/tests/cases/fourslash/codefixInferFromUsageNullish.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +////declare const a: string +////function wat([|b |]) { +//// b(a ?? 1); +////} + +verify.rangeAfterCodeFix("b: (arg0: string | number) => void");