mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Add support for Optional Chaining (#33294)
* Add support for Optional Chaining * Add grammar error for invalid tagged template, more tests * Prototype * PR feedback * Add errors for invalid assignments and a trailing '?.' * Add additional signature help test, fix lint warnings * Fix to insert text for completions * Add initial control-flow analysis for optional chains * PR Feedback and more tests * Update to control flow * Remove mangled smart quotes in comments * Fix lint, PR feedback * Updates to control flow * Switch to FlowCondition for CFA of optional chains * Fix ?. insertion for completions on type variables * Accept API baseline change * Clean up types * improve control-flow debug output * Revert Debug.formatControlFlowGraph helper
This commit is contained in:
+121
-24
@@ -797,6 +797,10 @@ namespace ts {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
bindVariableDeclarationFlow(<VariableDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
bindAccessExpressionFlow(<AccessExpression>node);
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
bindCallExpressionFlow(<CallExpression>node);
|
||||
break;
|
||||
@@ -941,7 +945,9 @@ namespace ts {
|
||||
}
|
||||
if (expression.kind === SyntaxKind.TrueKeyword && flags & FlowFlags.FalseCondition ||
|
||||
expression.kind === SyntaxKind.FalseKeyword && flags & FlowFlags.TrueCondition) {
|
||||
return unreachableFlow;
|
||||
if (!isOptionalChainRoot(expression.parent)) {
|
||||
return unreachableFlow;
|
||||
}
|
||||
}
|
||||
if (!isNarrowingExpression(expression)) {
|
||||
return antecedent;
|
||||
@@ -1015,23 +1021,28 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isTopLevelLogicalExpression(node: Node): boolean {
|
||||
while (node.parent.kind === SyntaxKind.ParenthesizedExpression ||
|
||||
node.parent.kind === SyntaxKind.PrefixUnaryExpression &&
|
||||
(<PrefixUnaryExpression>node.parent).operator === SyntaxKind.ExclamationToken) {
|
||||
while (isParenthesizedExpression(node.parent) ||
|
||||
isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.ExclamationToken) {
|
||||
node = node.parent;
|
||||
}
|
||||
return !isStatementCondition(node) && !isLogicalExpression(node.parent);
|
||||
return !isStatementCondition(node) &&
|
||||
!isLogicalExpression(node.parent) &&
|
||||
!(isOptionalChain(node.parent) && node.parent.expression === node);
|
||||
}
|
||||
|
||||
function doWithConditionalBranches<T>(action: (value: T) => void, value: T, trueTarget: FlowLabel, falseTarget: FlowLabel) {
|
||||
const savedTrueTarget = currentTrueTarget;
|
||||
const savedFalseTarget = currentFalseTarget;
|
||||
currentTrueTarget = trueTarget;
|
||||
currentFalseTarget = falseTarget;
|
||||
action(value);
|
||||
currentTrueTarget = savedTrueTarget;
|
||||
currentFalseTarget = savedFalseTarget;
|
||||
}
|
||||
|
||||
function bindCondition(node: Expression | undefined, trueTarget: FlowLabel, falseTarget: FlowLabel) {
|
||||
const saveTrueTarget = currentTrueTarget;
|
||||
const saveFalseTarget = currentFalseTarget;
|
||||
currentTrueTarget = trueTarget;
|
||||
currentFalseTarget = falseTarget;
|
||||
bind(node);
|
||||
currentTrueTarget = saveTrueTarget;
|
||||
currentFalseTarget = saveFalseTarget;
|
||||
if (!node || !isLogicalExpression(node)) {
|
||||
doWithConditionalBranches(bind, node, trueTarget, falseTarget);
|
||||
if (!node || !isLogicalExpression(node) && !(isOptionalChain(node) && isOutermostOptionalChain(node))) {
|
||||
addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node));
|
||||
addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node));
|
||||
}
|
||||
@@ -1536,22 +1547,96 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindCallExpressionFlow(node: CallExpression) {
|
||||
// If the target of the call expression is a function expression or arrow function we have
|
||||
// an immediately invoked function expression (IIFE). Initialize the flowNode property to
|
||||
// the current control flow (which includes evaluation of the IIFE arguments).
|
||||
let expr: Expression = node.expression;
|
||||
while (expr.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
expr = (<ParenthesizedExpression>expr).expression;
|
||||
function isOutermostOptionalChain(node: OptionalChain) {
|
||||
return !isOptionalChain(node.parent) || isOptionalChainRoot(node.parent) || node !== node.parent.expression;
|
||||
}
|
||||
|
||||
function bindOptionalExpression(node: Expression, trueTarget: FlowLabel, falseTarget: FlowLabel) {
|
||||
doWithConditionalBranches(bind, node, trueTarget, falseTarget);
|
||||
if (!isOptionalChain(node) || isOutermostOptionalChain(node)) {
|
||||
addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node));
|
||||
addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node));
|
||||
}
|
||||
if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) {
|
||||
bindEach(node.typeArguments);
|
||||
bindEach(node.arguments);
|
||||
bind(node.expression);
|
||||
}
|
||||
|
||||
function bindOptionalChainRest(node: OptionalChain) {
|
||||
bind(node.questionDotToken);
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
bind(node.name);
|
||||
break;
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
bind(node.argumentExpression);
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
bindEach(node.typeArguments);
|
||||
bindEach(node.arguments);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function bindOptionalChain(node: OptionalChain, trueTarget: FlowLabel, falseTarget: FlowLabel) {
|
||||
// For an optional chain, we emulate the behavior of a logical expression:
|
||||
//
|
||||
// a?.b -> a && a.b
|
||||
// a?.b.c -> a && a.b.c
|
||||
// a?.b?.c -> a && a.b && a.b.c
|
||||
// a?.[x = 1] -> a && a[x = 1]
|
||||
//
|
||||
// To do this we descend through the chain until we reach the root of a chain (the expression with a `?.`)
|
||||
// and build it's CFA graph as if it were the first condition (`a && ...`). Then we bind the rest
|
||||
// of the node as part of the "true" branch, and continue to do so as we ascend back up to the outermost
|
||||
// chain node. We then treat the entire node as the right side of the expression.
|
||||
const preChainLabel = node.questionDotToken ? createBranchLabel() : undefined;
|
||||
bindOptionalExpression(node.expression, preChainLabel || trueTarget, falseTarget);
|
||||
if (preChainLabel) {
|
||||
currentFlow = finishFlowLabel(preChainLabel);
|
||||
}
|
||||
doWithConditionalBranches(bindOptionalChainRest, node, trueTarget, falseTarget);
|
||||
if (isOutermostOptionalChain(node)) {
|
||||
addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node));
|
||||
addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node));
|
||||
}
|
||||
}
|
||||
|
||||
function bindOptionalChainFlow(node: OptionalChain) {
|
||||
if (isTopLevelLogicalExpression(node)) {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindOptionalChain(node, postExpressionLabel, postExpressionLabel);
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
}
|
||||
else {
|
||||
bindOptionalChain(node, currentTrueTarget!, currentFalseTarget!);
|
||||
}
|
||||
}
|
||||
|
||||
function bindAccessExpressionFlow(node: AccessExpression) {
|
||||
if (isOptionalChain(node)) {
|
||||
bindOptionalChainFlow(node);
|
||||
}
|
||||
else {
|
||||
bindEachChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
function bindCallExpressionFlow(node: CallExpression) {
|
||||
if (isOptionalChain(node)) {
|
||||
bindOptionalChainFlow(node);
|
||||
}
|
||||
else {
|
||||
// If the target of the call expression is a function expression or arrow function we have
|
||||
// an immediately invoked function expression (IIFE). Initialize the flowNode property to
|
||||
// the current control flow (which includes evaluation of the IIFE arguments).
|
||||
const expr = skipParentheses(node.expression);
|
||||
if (expr.kind === SyntaxKind.FunctionExpression || expr.kind === SyntaxKind.ArrowFunction) {
|
||||
bindEach(node.typeArguments);
|
||||
bindEach(node.arguments);
|
||||
bind(node.expression);
|
||||
}
|
||||
else {
|
||||
bindEachChild(node);
|
||||
}
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
const propertyAccess = <PropertyAccessExpression>node.expression;
|
||||
if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) {
|
||||
@@ -3297,6 +3382,10 @@ namespace ts {
|
||||
const callee = skipOuterExpressions(node.expression);
|
||||
const expression = node.expression;
|
||||
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
transformFlags |= TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
if (node.typeArguments) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
@@ -3692,6 +3781,10 @@ namespace ts {
|
||||
function computePropertyAccess(node: PropertyAccessExpression, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
transformFlags |= TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
// If a PropertyAccessExpression starts with a super keyword, then it is
|
||||
// ES6 syntax, and requires a lexical `this` binding.
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
@@ -3707,6 +3800,10 @@ namespace ts {
|
||||
function computeElementAccess(node: ElementAccessExpression, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
transformFlags |= TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
// If an ElementAccessExpression starts with a super keyword, then it is
|
||||
// ES6 syntax, and requires a lexical `this` binding.
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
|
||||
+159
-46
@@ -333,6 +333,10 @@ namespace ts {
|
||||
/** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
|
||||
let apparentArgumentCount: number | undefined;
|
||||
|
||||
// This object is reused for `checkOptionalExpression` return values to avoid frequent GC due to nursery object allocations.
|
||||
// This object represents a pool-size of 1.
|
||||
const pooledOptionalTypeResult: { isOptional: boolean, type: Type } = { isOptional: false, type: undefined! };
|
||||
|
||||
// for public members that accept a Node or one of its subtypes, we must guard against
|
||||
// synthetic nodes created during transformations by calling `getParseTreeNode`.
|
||||
// for most of these, we perform the guard only on `checker` to avoid any possible
|
||||
@@ -380,8 +384,10 @@ namespace ts {
|
||||
getParameterType: getTypeAtPosition,
|
||||
getPromisedTypeOfPromise,
|
||||
getReturnTypeOfSignature,
|
||||
isNullableType,
|
||||
getNullableType,
|
||||
getNonNullableType,
|
||||
getNonOptionalType: removeOptionalTypeMarker,
|
||||
getTypeArguments,
|
||||
typeToTypeNode: nodeBuilder.typeToTypeNode,
|
||||
indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
|
||||
@@ -546,6 +552,7 @@ namespace ts {
|
||||
getNullType: () => nullType,
|
||||
getESSymbolType: () => esSymbolType,
|
||||
getNeverType: () => neverType,
|
||||
getOptionalType: () => optionalType,
|
||||
isSymbolAccessible,
|
||||
getObjectFlags,
|
||||
isArrayType,
|
||||
@@ -648,6 +655,7 @@ namespace ts {
|
||||
const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
|
||||
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
||||
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType);
|
||||
const optionalType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
||||
const nullType = createIntrinsicType(TypeFlags.Null, "null");
|
||||
const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType);
|
||||
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
||||
@@ -1171,7 +1179,7 @@ namespace ts {
|
||||
// obtain item referenced by 'export='
|
||||
mainModule = resolveExternalModuleSymbol(mainModule);
|
||||
if (mainModule.flags & SymbolFlags.Namespace) {
|
||||
// If we’re merging an augmentation to a pattern ambient module, we want to
|
||||
// If we're merging an augmentation to a pattern ambient module, we want to
|
||||
// perform the merge unidirectionally from the augmentation ('a.foo') to
|
||||
// the pattern ('*.foo'), so that 'getMergedSymbol()' on a.foo gives you
|
||||
// all the exports both from the pattern and from the augmentation, but
|
||||
@@ -2657,7 +2665,7 @@ namespace ts {
|
||||
if (patternAmbientModules) {
|
||||
const pattern = findBestPatternMatch(patternAmbientModules, _ => _.pattern, moduleReference);
|
||||
if (pattern) {
|
||||
// If the module reference matched a pattern ambient module ('*.foo') but there’s also a
|
||||
// If the module reference matched a pattern ambient module ('*.foo') but there's also a
|
||||
// module augmentation by the specific name requested ('a.foo'), we store the merged symbol
|
||||
// by the augmentation name ('a.foo'), because asking for *.foo should not give you exports
|
||||
// from a.foo.
|
||||
@@ -8599,6 +8607,12 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function createOptionalCallSignature(signature: Signature) {
|
||||
const result = cloneSignature(signature);
|
||||
result.isOptionalCall = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getExpandedParameters(sig: Signature): readonly Symbol[] {
|
||||
if (sig.hasRestParameter) {
|
||||
const restIndex = sig.parameters.length - 1;
|
||||
@@ -10211,6 +10225,9 @@ namespace ts {
|
||||
signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) :
|
||||
getReturnTypeFromAnnotation(signature.declaration!) ||
|
||||
(nodeIsMissing((<FunctionLikeDeclaration>signature.declaration).body) ? anyType : getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration));
|
||||
if (signature.isOptionalCall) {
|
||||
type = propagateOptionalTypeMarker(type, /*wasOptional*/ true);
|
||||
}
|
||||
if (!popTypeResolution()) {
|
||||
if (signature.declaration) {
|
||||
const typeNode = getEffectiveReturnTypeNode(signature.declaration);
|
||||
@@ -15653,7 +15670,7 @@ namespace ts {
|
||||
for (const sourceProp of excludeProperties(getPropertiesOfType(source), excludedProperties)) {
|
||||
if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
|
||||
const sourceType = getTypeOfSymbol(sourceProp);
|
||||
if (!(sourceType === undefinedType || sourceType === undefinedWideningType)) {
|
||||
if (!(sourceType === undefinedType || sourceType === undefinedWideningType || sourceType === optionalType)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target));
|
||||
}
|
||||
@@ -16620,6 +16637,53 @@ namespace ts {
|
||||
return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
|
||||
}
|
||||
|
||||
function addOptionalTypeMarker(type: Type) {
|
||||
return strictNullChecks ? getUnionType([type, optionalType]) : type;
|
||||
}
|
||||
|
||||
function removeOptionalTypeMarker(type: Type): Type {
|
||||
return strictNullChecks ? filterType(type, t => t !== optionalType) : type;
|
||||
}
|
||||
|
||||
function propagateOptionalTypeMarker(type: Type, wasOptional: boolean) {
|
||||
return wasOptional ? addOptionalTypeMarker(type) : type;
|
||||
}
|
||||
|
||||
function createPooledOptionalTypeResult(isOptional: boolean, type: Type) {
|
||||
pooledOptionalTypeResult.isOptional = isOptional;
|
||||
pooledOptionalTypeResult.type = type;
|
||||
return pooledOptionalTypeResult;
|
||||
}
|
||||
|
||||
function checkOptionalExpression(
|
||||
parent: PropertyAccessExpression | QualifiedName | ElementAccessExpression | CallExpression,
|
||||
expression: Expression | QualifiedName,
|
||||
nullDiagnostic?: DiagnosticMessage,
|
||||
undefinedDiagnostic?: DiagnosticMessage,
|
||||
nullOrUndefinedDiagnostic?: DiagnosticMessage,
|
||||
) {
|
||||
let isOptional = false;
|
||||
let type = checkExpression(expression);
|
||||
if (isOptionalChain(parent)) {
|
||||
if (parent.questionDotToken) {
|
||||
// If we have a questionDotToken then we are an OptionalExpression and should remove `null` and
|
||||
// `undefined` from the type and add the optionalType to the result, if needed.
|
||||
isOptional = isNullableType(type);
|
||||
return createPooledOptionalTypeResult(isOptional, isOptional ? getNonNullableType(type) : type);
|
||||
}
|
||||
|
||||
// If we do not have a questionDotToken, then we are an OptionalChain and we remove the optionalType and
|
||||
// indicate whether we need to add optionalType back into the result.
|
||||
const nonOptionalType = removeOptionalTypeMarker(type);
|
||||
if (nonOptionalType !== type) {
|
||||
isOptional = true;
|
||||
type = nonOptionalType;
|
||||
}
|
||||
}
|
||||
|
||||
type = checkNonNullType(type, expression, nullDiagnostic, undefinedDiagnostic, nullOrUndefinedDiagnostic);
|
||||
return createPooledOptionalTypeResult(isOptional, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is source potentially coercible to target type under `==`.
|
||||
@@ -18105,7 +18169,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getFlowNodeId(flow: FlowNode): number {
|
||||
if (!flow.id) {
|
||||
if (!flow.id || flow.id < 0) {
|
||||
flow.id = nextFlowId;
|
||||
nextFlowId++;
|
||||
}
|
||||
@@ -18653,7 +18717,7 @@ namespace ts {
|
||||
// circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
|
||||
// target expression of an assertion.
|
||||
const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression, /*diagnostic*/ undefined) :
|
||||
node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) :
|
||||
node.expression.kind !== SyntaxKind.SuperKeyword ? checkOptionalExpression(node, node.expression).type :
|
||||
undefined;
|
||||
const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, SignatureKind.Call);
|
||||
const candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] :
|
||||
@@ -19571,7 +19635,7 @@ namespace ts {
|
||||
|
||||
function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type {
|
||||
if (hasMatchingArgument(callExpression, reference)) {
|
||||
const signature = getEffectsSignature(callExpression);
|
||||
const signature = assumeTrue || !isCallChain(callExpression) ? getEffectsSignature(callExpression) : undefined;
|
||||
const predicate = signature && getTypePredicateOfSignature(signature);
|
||||
if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) {
|
||||
return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue);
|
||||
@@ -19614,6 +19678,10 @@ namespace ts {
|
||||
// Narrow the given type based on the given expression having the assumed boolean value. The returned type
|
||||
// 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)) {
|
||||
return narrowTypeByOptionality(type, expr, assumeTrue);
|
||||
}
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
@@ -19635,6 +19703,19 @@ namespace ts {
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByOptionality(type: Type, expr: Expression, assumePresent: boolean): Type {
|
||||
if (isMatchingReference(reference, expr)) {
|
||||
return getTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull);
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(expr, declaredType)) {
|
||||
return narrowTypeByDiscriminant(type, <AccessExpression>expr, t => getTypeWithFacts(t, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull));
|
||||
}
|
||||
if (containsMatchingReferenceDiscriminant(reference, expr)) {
|
||||
return declaredType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeOfSymbolAtLocation(symbol: Symbol, location: Node) {
|
||||
@@ -22505,12 +22586,12 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function isNullableType(type: Type) {
|
||||
return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable);
|
||||
}
|
||||
|
||||
function getNonNullableTypeIfNeeded(type: Type) {
|
||||
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
|
||||
if (kind) {
|
||||
return getNonNullableType(type);
|
||||
}
|
||||
return type;
|
||||
return isNullableType(type) ? getNonNullableType(type) : type;
|
||||
}
|
||||
|
||||
function checkNonNullType(
|
||||
@@ -22561,8 +22642,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
|
||||
let propType: Type;
|
||||
const leftType = checkNonNullExpression(left);
|
||||
const { isOptional, type: leftType } = checkOptionalExpression(node, left);
|
||||
const parentSymbol = getNodeLinks(left).resolvedSymbol;
|
||||
const assignmentKind = getAssignmentTargetKind(node);
|
||||
const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType);
|
||||
@@ -22576,6 +22656,8 @@ namespace ts {
|
||||
if (isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) {
|
||||
markAliasReferenced(parentSymbol, node);
|
||||
}
|
||||
|
||||
let propType: Type;
|
||||
if (!prop) {
|
||||
const indexInfo = assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined;
|
||||
if (!(indexInfo && indexInfo.type)) {
|
||||
@@ -22614,7 +22696,7 @@ namespace ts {
|
||||
}
|
||||
propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
|
||||
}
|
||||
return getFlowTypeOfAccessExpression(node, prop, propType, right);
|
||||
return propagateOptionalTypeMarker(getFlowTypeOfAccessExpression(node, prop, propType, right), isOptional);
|
||||
}
|
||||
|
||||
function getFlowTypeOfAccessExpression(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, propType: Type, errorNode: Node) {
|
||||
@@ -22971,9 +23053,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkIndexedAccess(node: ElementAccessExpression): Type {
|
||||
const exprType = checkNonNullExpression(node.expression);
|
||||
const { isOptional, type: exprType } = checkOptionalExpression(node, node.expression);
|
||||
const objectType = getAssignmentTargetKind(node) !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType;
|
||||
|
||||
const indexExpression = node.argumentExpression;
|
||||
const indexType = checkExpression(indexExpression);
|
||||
|
||||
@@ -22991,7 +23072,7 @@ namespace ts {
|
||||
AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) :
|
||||
AccessFlags.None;
|
||||
const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
|
||||
return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
|
||||
return propagateOptionalTypeMarker(checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node), isOptional);
|
||||
}
|
||||
|
||||
function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
|
||||
@@ -23074,7 +23155,7 @@ namespace ts {
|
||||
// interface B extends A { (x: 'foo'): string }
|
||||
// const b: B;
|
||||
// b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
|
||||
function reorderCandidates(signatures: readonly Signature[], result: Signature[]): void {
|
||||
function reorderCandidates(signatures: readonly Signature[], result: Signature[], isOptionalCall: boolean): void {
|
||||
let lastParent: Node | undefined;
|
||||
let lastSymbol: Symbol | undefined;
|
||||
let cutoffIndex = 0;
|
||||
@@ -23116,7 +23197,7 @@ namespace ts {
|
||||
spliceIndex = index;
|
||||
}
|
||||
|
||||
result.splice(spliceIndex, 0, signature);
|
||||
result.splice(spliceIndex, 0, isOptionalCall ? createOptionalCallSignature(signature) : signature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23769,7 +23850,7 @@ namespace ts {
|
||||
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
|
||||
}
|
||||
|
||||
function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, fallbackError?: DiagnosticMessage): Signature {
|
||||
function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, isOptionalCall: boolean, fallbackError?: DiagnosticMessage): Signature {
|
||||
const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
|
||||
const isDecorator = node.kind === SyntaxKind.Decorator;
|
||||
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
|
||||
@@ -23788,7 +23869,7 @@ namespace ts {
|
||||
|
||||
const candidates = candidatesOutArray || [];
|
||||
// reorderCandidates fills up the candidates array directly
|
||||
reorderCandidates(signatures, candidates);
|
||||
reorderCandidates(signatures, candidates, isOptionalCall);
|
||||
if (!candidates.length) {
|
||||
if (reportErrors) {
|
||||
diagnostics.add(getDiagnosticForCallNode(node, Diagnostics.Call_target_does_not_contain_any_signatures));
|
||||
@@ -24172,13 +24253,14 @@ namespace ts {
|
||||
const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!);
|
||||
if (baseTypeNode) {
|
||||
const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
|
||||
return resolveCall(node, baseConstructors, candidatesOutArray, checkMode);
|
||||
return resolveCall(node, baseConstructors, candidatesOutArray, checkMode, /*isOptional*/ false);
|
||||
}
|
||||
}
|
||||
return resolveUntypedCall(node);
|
||||
}
|
||||
|
||||
const funcType = checkNonNullExpression(
|
||||
const { isOptional, type: funcType } = checkOptionalExpression(
|
||||
node,
|
||||
node.expression,
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null,
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined,
|
||||
@@ -24188,8 +24270,8 @@ namespace ts {
|
||||
if (funcType === silentNeverType) {
|
||||
return silentNeverSignature;
|
||||
}
|
||||
const apparentType = getApparentType(funcType);
|
||||
|
||||
const apparentType = getApparentType(funcType);
|
||||
if (apparentType === errorType) {
|
||||
// Another error has already been reported
|
||||
return resolveErrorCall(node);
|
||||
@@ -24253,7 +24335,8 @@ namespace ts {
|
||||
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
|
||||
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, isOptional);
|
||||
}
|
||||
|
||||
function isGenericFunctionReturningFunction(signature: Signature) {
|
||||
@@ -24324,7 +24407,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, constructSignatures, candidatesOutArray, checkMode);
|
||||
return resolveCall(node, constructSignatures, candidatesOutArray, checkMode, /*isOptional*/ false);
|
||||
}
|
||||
|
||||
// If expressionType's apparent type is an object type with no construct signatures but
|
||||
@@ -24333,7 +24416,7 @@ namespace ts {
|
||||
// operation is Any. It is an error to have a Void this type.
|
||||
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
|
||||
if (callSignatures.length) {
|
||||
const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode);
|
||||
const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode, /*isOptional*/ false);
|
||||
if (!noImplicitAny) {
|
||||
if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
|
||||
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
|
||||
@@ -24548,7 +24631,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, /*isOptional*/ false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24611,7 +24694,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, headMessage);
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, /*isOptional*/ false, headMessage);
|
||||
}
|
||||
|
||||
function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature {
|
||||
@@ -24664,7 +24747,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, signatures, candidatesOutArray, checkMode);
|
||||
return resolveCall(node, signatures, candidatesOutArray, checkMode, /*isOptional*/ false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24851,18 +24934,20 @@ namespace ts {
|
||||
getTypeOfDottedName(node.expression, diagnostic);
|
||||
}
|
||||
}
|
||||
let jsAssignmentType: Type | undefined;
|
||||
|
||||
if (isInJSFile(node)) {
|
||||
const decl = getDeclarationOfExpando(node);
|
||||
if (decl) {
|
||||
const jsSymbol = getSymbolOfNode(decl);
|
||||
if (jsSymbol && hasEntries(jsSymbol.exports)) {
|
||||
jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, undefined, undefined);
|
||||
(jsAssignmentType as ObjectType).objectFlags |= ObjectFlags.JSLiteral;
|
||||
const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, undefined, undefined);
|
||||
jsAssignmentType.objectFlags |= ObjectFlags.JSLiteral;
|
||||
return getIntersectionType([returnType, jsAssignmentType]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsAssignmentType ? getIntersectionType([returnType, jsAssignmentType]) : returnType;
|
||||
|
||||
return returnType;
|
||||
}
|
||||
|
||||
function isSymbolOrSymbolForCall(node: Node) {
|
||||
@@ -24969,7 +25054,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
|
||||
checkGrammarTypeArguments(node, node.typeArguments);
|
||||
if (!checkGrammarTaggedTemplateChain(node)) checkGrammarTypeArguments(node, node.typeArguments);
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject);
|
||||
}
|
||||
@@ -25886,13 +25971,17 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkReferenceExpression(expr: Expression, invalidReferenceMessage: DiagnosticMessage): boolean {
|
||||
function checkReferenceExpression(expr: Expression, invalidReferenceMessage: DiagnosticMessage, invalidOptionalChainMessage: DiagnosticMessage): boolean {
|
||||
// References are combinations of identifiers, parentheses, and property accesses.
|
||||
const node = skipOuterExpressions(expr, OuterExpressionKinds.Assertions | OuterExpressionKinds.Parentheses);
|
||||
if (node.kind !== SyntaxKind.Identifier && node.kind !== SyntaxKind.PropertyAccessExpression && node.kind !== SyntaxKind.ElementAccessExpression) {
|
||||
error(expr, invalidReferenceMessage);
|
||||
return false;
|
||||
}
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
error(expr, invalidOptionalChainMessage);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26002,7 +26091,10 @@ namespace ts {
|
||||
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
|
||||
if (ok) {
|
||||
// run check only if former checks succeeded to avoid reporting cascading errors
|
||||
checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
|
||||
checkReferenceExpression(
|
||||
node.operand,
|
||||
Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access,
|
||||
Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access);
|
||||
}
|
||||
return getUnaryResultType(operandType);
|
||||
}
|
||||
@@ -26020,7 +26112,10 @@ namespace ts {
|
||||
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
|
||||
if (ok) {
|
||||
// run check only if former checks succeeded to avoid reporting cascading errors
|
||||
checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
|
||||
checkReferenceExpression(
|
||||
node.operand,
|
||||
Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access,
|
||||
Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access);
|
||||
}
|
||||
return getUnaryResultType(operandType);
|
||||
}
|
||||
@@ -26270,7 +26365,10 @@ namespace ts {
|
||||
const error = target.parent.kind === SyntaxKind.SpreadAssignment ?
|
||||
Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
|
||||
Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
|
||||
if (checkReferenceExpression(target, error)) {
|
||||
const optionalError = target.parent.kind === SyntaxKind.SpreadAssignment ?
|
||||
Diagnostics.The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access :
|
||||
Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access;
|
||||
if (checkReferenceExpression(target, error, optionalError)) {
|
||||
checkTypeAssignableToAndOptionallyElaborate(sourceType, targetType, target, target);
|
||||
}
|
||||
return sourceType;
|
||||
@@ -26476,7 +26574,7 @@ namespace ts {
|
||||
|
||||
if (!resultType) {
|
||||
// Types that have a reasonably good chance of being a valid operand type.
|
||||
// If both types have an awaited type of one of these, we’ll assume the user
|
||||
// If both types have an awaited type of one of these, we'll assume the user
|
||||
// might be missing an await without doing an exhaustive check that inserting
|
||||
// await(s) will actually be a completely valid binary expression.
|
||||
const closeEnoughKind = TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.AnyOrUnknown;
|
||||
@@ -26614,7 +26712,9 @@ namespace ts {
|
||||
// A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
|
||||
// and the type of the non-compound operation to be assignable to the type of VarExpr.
|
||||
|
||||
if (checkReferenceExpression(left, Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)
|
||||
if (checkReferenceExpression(left,
|
||||
Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access,
|
||||
Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access)
|
||||
&& (!isIdentifier(left) || unescapeLeadingUnderscores(left.escapedText) !== "exports")) {
|
||||
// to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
|
||||
checkTypeAssignableToAndOptionallyElaborate(valueType, leftType, left, right);
|
||||
@@ -27113,11 +27213,11 @@ namespace ts {
|
||||
const expr = skipParentheses(node);
|
||||
// Optimize for the common case of a call to a function with a single non-generic call
|
||||
// signature where we can just fetch the return type without checking the arguments.
|
||||
if (expr.kind === SyntaxKind.CallExpression && (<CallExpression>expr).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
|
||||
const funcType = checkNonNullExpression((<CallExpression>expr).expression);
|
||||
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
|
||||
const { isOptional, type: funcType } = checkOptionalExpression(expr, expr.expression);
|
||||
const signature = getSingleCallSignature(funcType);
|
||||
if (signature && !signature.typeParameters) {
|
||||
return getReturnTypeOfSignature(signature);
|
||||
return propagateOptionalTypeMarker(getReturnTypeOfSignature(signature), isOptional);
|
||||
}
|
||||
}
|
||||
else if (isAssertionExpression(expr) && !isConstTypeReference(expr.type)) {
|
||||
@@ -29958,7 +30058,10 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const leftType = checkExpression(varExpr);
|
||||
checkReferenceExpression(varExpr, Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access);
|
||||
checkReferenceExpression(
|
||||
varExpr,
|
||||
Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access,
|
||||
Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access);
|
||||
|
||||
// iteratedType will be undefined if the rightType was missing properties/signatures
|
||||
// required to get its iteratedType (like [Symbol.iterator] or next). This may be
|
||||
@@ -30008,7 +30111,10 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// run check only former check succeeded to avoid cascading errors
|
||||
checkReferenceExpression(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access);
|
||||
checkReferenceExpression(
|
||||
varExpr,
|
||||
Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access,
|
||||
Diagnostics.The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34799,6 +34905,13 @@ namespace ts {
|
||||
checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
|
||||
}
|
||||
|
||||
function checkGrammarTaggedTemplateChain(node: TaggedTemplateExpression): boolean {
|
||||
if (node.questionDotToken || node.flags & NodeFlags.OptionalChain) {
|
||||
return grammarErrorOnNode(node.template, Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkGrammarForOmittedArgument(args: NodeArray<Expression> | undefined): boolean {
|
||||
if (args) {
|
||||
for (const arg of args) {
|
||||
|
||||
@@ -187,6 +187,14 @@ namespace ts {
|
||||
assertNode)
|
||||
: noop;
|
||||
|
||||
export const assertNotNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node | undefined, test: ((node: Node | undefined) => boolean) | undefined, message?: string): void => assert(
|
||||
test === undefined || !test(node),
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node!.kind)} should not have passed test '${getFunctionName(test!)}'.`,
|
||||
assertNode)
|
||||
: noop;
|
||||
|
||||
export const assertOptionalNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, test: (node: Node) => boolean, message?: string): void => assert(
|
||||
test === undefined || node === undefined || test(node),
|
||||
@@ -260,5 +268,6 @@ namespace ts {
|
||||
|
||||
isDebugInfoEnabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1039,6 +1039,10 @@
|
||||
"category": "Error",
|
||||
"code": 1357
|
||||
},
|
||||
"Tagged template expressions are not permitted in an optional chain.": {
|
||||
"category": "Error",
|
||||
"code": 1358
|
||||
},
|
||||
|
||||
"The types of '{0}' are incompatible between these types.": {
|
||||
"category": "Error",
|
||||
@@ -2747,6 +2751,27 @@
|
||||
"category": "Error",
|
||||
"code": 2776
|
||||
},
|
||||
"The operand of an increment or decrement operator may not be an optional property access.": {
|
||||
"category": "Error",
|
||||
"code": 2777
|
||||
},
|
||||
"The target of an object rest assignment may not be an optional property access.": {
|
||||
"category": "Error",
|
||||
"code": 2778
|
||||
},
|
||||
"The left-hand side of an assignment expression may not be an optional property access.": {
|
||||
"category": "Error",
|
||||
"code": 2779
|
||||
},
|
||||
"The left-hand side of a 'for...in' statement may not be an optional property access.": {
|
||||
"category": "Error",
|
||||
"code": 2780
|
||||
},
|
||||
"The left-hand side of a 'for...of' statement may not be an optional property access.": {
|
||||
"category": "Error",
|
||||
"code": 2781
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
|
||||
+69
-41
@@ -858,6 +858,8 @@ namespace ts {
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[] | undefined;
|
||||
let hasWrittenComment = false;
|
||||
let commentsDisabled = !!printerOptions.removeComments;
|
||||
let lastNode: Node | undefined;
|
||||
let lastSubstitution: Node | undefined;
|
||||
const { enter: enterComment, exit: exitComment } = performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment");
|
||||
|
||||
reset();
|
||||
@@ -1080,8 +1082,7 @@ namespace ts {
|
||||
setSourceFile(sourceFile);
|
||||
}
|
||||
|
||||
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, node);
|
||||
pipelinePhase(hint, node);
|
||||
pipelineEmit(hint, node);
|
||||
}
|
||||
|
||||
function setSourceFile(sourceFile: SourceFile | undefined) {
|
||||
@@ -1113,6 +1114,8 @@ namespace ts {
|
||||
currentSourceFile = undefined!;
|
||||
currentLineMap = undefined!;
|
||||
detachedCommentsInfo = undefined;
|
||||
lastNode = undefined;
|
||||
lastSubstitution = undefined;
|
||||
setWriter(/*output*/ undefined, /*_sourceMapGenerator*/ undefined);
|
||||
}
|
||||
|
||||
@@ -1120,24 +1123,47 @@ namespace ts {
|
||||
return currentLineMap || (currentLineMap = getLineStarts(currentSourceFile!));
|
||||
}
|
||||
|
||||
function emit(node: Node): Node;
|
||||
function emit(node: Node | undefined): Node | undefined;
|
||||
function emit(node: Node | undefined) {
|
||||
if (node === undefined) return;
|
||||
|
||||
const prevSourceFileTextKind = recordBundleFileInternalSectionStart(node);
|
||||
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, node);
|
||||
pipelinePhase(EmitHint.Unspecified, node);
|
||||
const substitute = pipelineEmit(EmitHint.Unspecified, node);
|
||||
recordBundleFileInternalSectionEnd(prevSourceFileTextKind);
|
||||
return substitute;
|
||||
}
|
||||
|
||||
function emitIdentifierName(node: Identifier | undefined) {
|
||||
function emitIdentifierName(node: Identifier): Node;
|
||||
function emitIdentifierName(node: Identifier | undefined): Node | undefined;
|
||||
function emitIdentifierName(node: Identifier | undefined): Node | undefined {
|
||||
if (node === undefined) return;
|
||||
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, node);
|
||||
pipelinePhase(EmitHint.IdentifierName, node);
|
||||
return pipelineEmit(EmitHint.IdentifierName, node);
|
||||
}
|
||||
|
||||
function emitExpression(node: Expression | undefined) {
|
||||
function emitExpression(node: Expression): Node;
|
||||
function emitExpression(node: Expression | undefined): Node | undefined;
|
||||
function emitExpression(node: Expression | undefined): Node | undefined {
|
||||
if (node === undefined) return;
|
||||
return pipelineEmit(EmitHint.Expression, node);
|
||||
}
|
||||
|
||||
function pipelineEmit(emitHint: EmitHint, node: Node) {
|
||||
const savedLastNode = lastNode;
|
||||
const savedLastSubstitution = lastSubstitution;
|
||||
lastNode = node;
|
||||
lastSubstitution = undefined;
|
||||
|
||||
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, node);
|
||||
pipelinePhase(EmitHint.Expression, node);
|
||||
pipelinePhase(emitHint, node);
|
||||
|
||||
Debug.assert(lastNode === node);
|
||||
|
||||
const substitute = lastSubstitution;
|
||||
lastNode = savedLastNode;
|
||||
lastSubstitution = savedLastSubstitution;
|
||||
|
||||
return substitute || node;
|
||||
}
|
||||
|
||||
function getPipelinePhase(phase: PipelinePhase, node: Node) {
|
||||
@@ -1179,11 +1205,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithNotification(hint: EmitHint, node: Node) {
|
||||
Debug.assert(lastNode === node);
|
||||
const pipelinePhase = getNextPipelinePhase(PipelinePhase.Notification, node);
|
||||
onEmitNode(hint, node, pipelinePhase);
|
||||
Debug.assert(lastNode === node);
|
||||
}
|
||||
|
||||
function pipelineEmitWithHint(hint: EmitHint, node: Node): void {
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
if (hint === EmitHint.SourceFile) return emitSourceFile(cast(node, isSourceFile));
|
||||
if (hint === EmitHint.IdentifierName) return emitIdentifier(cast(node, isIdentifier));
|
||||
if (hint === EmitHint.MappedTypeParameter) return emitMappedTypeParameter(cast(node, isTypeParameterDeclaration));
|
||||
@@ -1495,7 +1524,7 @@ namespace ts {
|
||||
if (isExpression(node)) {
|
||||
hint = EmitHint.Expression;
|
||||
if (substituteNode !== noEmitSubstitution) {
|
||||
node = substituteNode(hint, node);
|
||||
lastSubstitution = node = substituteNode(hint, node);
|
||||
}
|
||||
}
|
||||
else if (isToken(node)) {
|
||||
@@ -1611,8 +1640,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) {
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
const pipelinePhase = getNextPipelinePhase(PipelinePhase.Substitution, node);
|
||||
pipelinePhase(hint, substituteNode(hint, node));
|
||||
lastSubstitution = substituteNode(hint, node);
|
||||
pipelinePhase(hint, lastSubstitution);
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
}
|
||||
|
||||
function getHelpersFromBundledSourceFiles(bundle: Bundle): string[] | undefined {
|
||||
@@ -2116,8 +2148,7 @@ namespace ts {
|
||||
}
|
||||
writePunctuation("[");
|
||||
|
||||
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, node.typeParameter);
|
||||
pipelinePhase(EmitHint.MappedTypeParameter, node.typeParameter);
|
||||
pipelineEmit(EmitHint.MappedTypeParameter, node.typeParameter);
|
||||
|
||||
writePunctuation("]");
|
||||
if (node.questionToken) {
|
||||
@@ -2215,34 +2246,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitPropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
let indentBeforeDot = false;
|
||||
let indentAfterDot = false;
|
||||
const dotRangeFirstCommentStart = skipTrivia(
|
||||
currentSourceFile!.text,
|
||||
node.expression.end,
|
||||
/*stopAfterLineBreak*/ false,
|
||||
/*stopAtComments*/ true
|
||||
);
|
||||
const dotRangeStart = skipTrivia(currentSourceFile!.text, dotRangeFirstCommentStart);
|
||||
const dotRangeEnd = dotRangeStart + 1;
|
||||
if (!(getEmitFlags(node) & EmitFlags.NoIndentation)) {
|
||||
const dotToken = createToken(SyntaxKind.DotToken);
|
||||
dotToken.pos = node.expression.end;
|
||||
dotToken.end = dotRangeEnd;
|
||||
indentBeforeDot = needsIndentation(node, node.expression, dotToken);
|
||||
indentAfterDot = needsIndentation(node, dotToken, node.name);
|
||||
}
|
||||
const expression = cast(emitExpression(node.expression), isExpression);
|
||||
const token = getDotOrQuestionDotToken(node);
|
||||
const indentBeforeDot = needsIndentation(node, node.expression, token);
|
||||
const indentAfterDot = needsIndentation(node, token, node.name);
|
||||
|
||||
emitExpression(node.expression);
|
||||
increaseIndentIf(indentBeforeDot, /*writeSpaceIfNotIndenting*/ false);
|
||||
|
||||
const dotHasCommentTrivia = dotRangeFirstCommentStart !== dotRangeStart;
|
||||
const shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression, dotHasCommentTrivia);
|
||||
const shouldEmitDotDot =
|
||||
token.kind !== SyntaxKind.QuestionDotToken &&
|
||||
mayNeedDotDotForPropertyAccess(expression) &&
|
||||
!writer.hasTrailingComment() &&
|
||||
!writer.hasTrailingWhitespace();
|
||||
|
||||
if (shouldEmitDotDot) {
|
||||
writePunctuation(".");
|
||||
}
|
||||
emitTokenWithComment(SyntaxKind.DotToken, node.expression.end, writePunctuation, node);
|
||||
|
||||
emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
|
||||
increaseIndentIf(indentAfterDot, /*writeSpaceIfNotIndenting*/ false);
|
||||
emit(node.name);
|
||||
decreaseIndentIf(indentBeforeDot, indentAfterDot);
|
||||
@@ -2250,28 +2271,27 @@ namespace ts {
|
||||
|
||||
// 1..toString is a valid property access, emit a dot after the literal
|
||||
// Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
|
||||
function needsDotDotForPropertyAccess(expression: Expression, dotHasTrivia: boolean) {
|
||||
function mayNeedDotDotForPropertyAccess(expression: Expression) {
|
||||
expression = skipPartiallyEmittedExpressions(expression);
|
||||
if (isNumericLiteral(expression)) {
|
||||
// check if numeric literal is a decimal literal that was originally written with a dot
|
||||
const text = getLiteralTextOfNode(<LiteralExpression>expression, /*neverAsciiEscape*/ true);
|
||||
// If he number will be printed verbatim and it doesn't already contain a dot, add one
|
||||
// if the expression doesn't have any comments that will be emitted.
|
||||
return !expression.numericLiteralFlags && !stringContains(text, tokenToString(SyntaxKind.DotToken)!) &&
|
||||
(!dotHasTrivia || printerOptions.removeComments);
|
||||
return !expression.numericLiteralFlags && !stringContains(text, tokenToString(SyntaxKind.DotToken)!);
|
||||
}
|
||||
else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) {
|
||||
// check if constant enum value is integer
|
||||
const constantValue = getConstantValue(expression);
|
||||
// isFinite handles cases when constantValue is undefined
|
||||
return typeof constantValue === "number" && isFinite(constantValue)
|
||||
&& Math.floor(constantValue) === constantValue
|
||||
&& printerOptions.removeComments;
|
||||
&& Math.floor(constantValue) === constantValue;
|
||||
}
|
||||
}
|
||||
|
||||
function emitElementAccessExpression(node: ElementAccessExpression) {
|
||||
emitExpression(node.expression);
|
||||
emit(node.questionDotToken);
|
||||
emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node);
|
||||
emitExpression(node.argumentExpression);
|
||||
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node);
|
||||
@@ -2279,6 +2299,7 @@ namespace ts {
|
||||
|
||||
function emitCallExpression(node: CallExpression) {
|
||||
emitExpression(node.expression);
|
||||
emit(node.questionDotToken);
|
||||
emitTypeArguments(node, node.typeArguments);
|
||||
emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments);
|
||||
}
|
||||
@@ -3742,8 +3763,7 @@ namespace ts {
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
if (isEmptyStatement(node)) {
|
||||
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, node);
|
||||
pipelinePhase(EmitHint.EmbeddedStatement, node);
|
||||
pipelineEmit(EmitHint.EmbeddedStatement, node);
|
||||
}
|
||||
else {
|
||||
emit(node);
|
||||
@@ -4214,6 +4234,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function needsIndentation(parent: Node, node1: Node, node2: Node): boolean {
|
||||
if (getEmitFlags(parent) & EmitFlags.NoIndentation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent = skipSynthesizedParentheses(parent);
|
||||
node1 = skipSynthesizedParentheses(node1);
|
||||
node2 = skipSynthesizedParentheses(node2);
|
||||
@@ -4669,6 +4693,7 @@ namespace ts {
|
||||
// Comments
|
||||
|
||||
function pipelineEmitWithComments(hint: EmitHint, node: Node) {
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
enterComment();
|
||||
hasWrittenComment = false;
|
||||
const emitFlags = getEmitFlags(node);
|
||||
@@ -4735,6 +4760,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
exitComment();
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
}
|
||||
|
||||
function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
|
||||
@@ -4981,6 +5007,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) {
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
const pipelinePhase = getNextPipelinePhase(PipelinePhase.SourceMaps, node);
|
||||
if (isUnparsedSource(node) || isUnparsedPrepend(node)) {
|
||||
pipelinePhase(hint, node);
|
||||
@@ -5023,6 +5050,7 @@ namespace ts {
|
||||
emitSourcePos(source, end);
|
||||
}
|
||||
}
|
||||
Debug.assert(lastNode === node || lastSubstitution === node);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1065,6 +1065,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier) {
|
||||
Debug.assert(!(node.flags & NodeFlags.OptionalChain), "Cannot update a PropertyAccessChain using updatePropertyAccess. Use updatePropertyAccessChain instead.");
|
||||
// Because we are updating existed propertyAccess we want to inherit its emitFlags
|
||||
// instead of using the default from createPropertyAccess
|
||||
return node.expression !== expression
|
||||
@@ -1073,6 +1074,27 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier) {
|
||||
const node = <PropertyAccessChain>createSynthesizedNode(SyntaxKind.PropertyAccessExpression);
|
||||
node.flags |= NodeFlags.OptionalChain;
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.questionDotToken = questionDotToken;
|
||||
node.name = asName(name);
|
||||
setEmitFlags(node, EmitFlags.NoIndentation);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier) {
|
||||
Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead.");
|
||||
// Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags
|
||||
// instead of using the default from createPropertyAccess
|
||||
return node.expression !== expression
|
||||
|| node.questionDotToken !== questionDotToken
|
||||
|| node.name !== name
|
||||
? updateNode(setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), getEmitFlags(node)), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createElementAccess(expression: Expression, index: number | Expression) {
|
||||
const node = <ElementAccessExpression>createSynthesizedNode(SyntaxKind.ElementAccessExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
@@ -1081,12 +1103,31 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) {
|
||||
Debug.assert(!(node.flags & NodeFlags.OptionalChain), "Cannot update an ElementAccessChain using updateElementAccess. Use updateElementAccessChain instead.");
|
||||
return node.expression !== expression
|
||||
|| node.argumentExpression !== argumentExpression
|
||||
? updateNode(createElementAccess(expression, argumentExpression), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression) {
|
||||
const node = <ElementAccessChain>createSynthesizedNode(SyntaxKind.ElementAccessExpression);
|
||||
node.flags |= NodeFlags.OptionalChain;
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.questionDotToken = questionDotToken;
|
||||
node.argumentExpression = asExpression(index);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression) {
|
||||
Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update an ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead.");
|
||||
return node.expression !== expression
|
||||
|| node.questionDotToken !== questionDotToken
|
||||
|| node.argumentExpression !== argumentExpression
|
||||
? updateNode(createElementAccessChain(expression, questionDotToken, argumentExpression), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createCall(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) {
|
||||
const node = <CallExpression>createSynthesizedNode(SyntaxKind.CallExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
@@ -1096,6 +1137,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function updateCall(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) {
|
||||
Debug.assert(!(node.flags & NodeFlags.OptionalChain), "Cannot update a CallChain using updateCall. Use updateCallChain instead.");
|
||||
return node.expression !== expression
|
||||
|| node.typeArguments !== typeArguments
|
||||
|| node.arguments !== argumentsArray
|
||||
@@ -1103,6 +1145,26 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) {
|
||||
const node = <CallChain>createSynthesizedNode(SyntaxKind.CallExpression);
|
||||
node.flags |= NodeFlags.OptionalChain;
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.questionDotToken = questionDotToken;
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
node.arguments = parenthesizeListElements(createNodeArray(argumentsArray));
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]) {
|
||||
Debug.assert(!!(node.flags & NodeFlags.OptionalChain), "Cannot update a CallExpression using updateCallChain. Use updateCall instead.");
|
||||
return node.expression !== expression
|
||||
|| node.questionDotToken !== questionDotToken
|
||||
|| node.typeArguments !== typeArguments
|
||||
|| node.arguments !== argumentsArray
|
||||
? updateNode(createCallChain(expression, questionDotToken, typeArguments, argumentsArray), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createNew(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined) {
|
||||
const node = <NewExpression>createSynthesizedNode(SyntaxKind.NewExpression);
|
||||
node.expression = parenthesizeForNew(expression);
|
||||
@@ -2776,6 +2838,22 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createSyntheticReferenceExpression(expression: Expression, thisArg: Expression) {
|
||||
const node = <SyntheticReferenceExpression>createSynthesizedNode(SyntaxKind.SyntheticReferenceExpression);
|
||||
node.expression = expression;
|
||||
node.thisArg = thisArg;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function updateSyntheticReferenceExpression(node: SyntheticReferenceExpression, expression: Expression, thisArg: Expression) {
|
||||
return node.expression !== expression
|
||||
|| node.thisArg !== thisArg
|
||||
? updateNode(createSyntheticReferenceExpression(expression, thisArg), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createBundle(sourceFiles: readonly SourceFile[], prepends: readonly (UnparsedSource | InputFiles)[] = emptyArray) {
|
||||
const node = <Bundle>createNode(SyntaxKind.Bundle);
|
||||
node.prepends = prepends;
|
||||
|
||||
+109
-46
@@ -212,17 +212,21 @@ namespace ts {
|
||||
return visitNodes(cbNode, cbNodes, (<ObjectLiteralExpression>node).properties);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return visitNode(cbNode, (<PropertyAccessExpression>node).expression) ||
|
||||
visitNode(cbNode, (<PropertyAccessExpression>node).questionDotToken) ||
|
||||
visitNode(cbNode, (<PropertyAccessExpression>node).name);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return visitNode(cbNode, (<ElementAccessExpression>node).expression) ||
|
||||
visitNode(cbNode, (<ElementAccessExpression>node).questionDotToken) ||
|
||||
visitNode(cbNode, (<ElementAccessExpression>node).argumentExpression);
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
return visitNode(cbNode, (<CallExpression>node).expression) ||
|
||||
visitNode(cbNode, (<CallExpression>node).questionDotToken) ||
|
||||
visitNodes(cbNode, cbNodes, (<CallExpression>node).typeArguments) ||
|
||||
visitNodes(cbNode, cbNodes, (<CallExpression>node).arguments);
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return visitNode(cbNode, (<TaggedTemplateExpression>node).tag) ||
|
||||
visitNode(cbNode, (<TaggedTemplateExpression>node).questionDotToken) ||
|
||||
visitNodes(cbNode, cbNodes, (<TaggedTemplateExpression>node).typeArguments) ||
|
||||
visitNode(cbNode, (<TaggedTemplateExpression>node).template);
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
@@ -4243,7 +4247,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Now, we *may* be complete. However, we might have consumed the start of a
|
||||
// CallExpression. As such, we need to consume the rest of it here to be complete.
|
||||
// CallExpression or OptionalExpression. As such, we need to consume the rest
|
||||
// of it here to be complete.
|
||||
return parseCallExpressionRest(expression);
|
||||
}
|
||||
|
||||
@@ -4296,7 +4301,7 @@ namespace ts {
|
||||
// Because CallExpression and MemberExpression are left recursive, we need to bottom out
|
||||
// of the recursion immediately. So we parse out a primary expression to start with.
|
||||
const expression = parsePrimaryExpression();
|
||||
return parseMemberExpressionRest(expression);
|
||||
return parseMemberExpressionRest(expression, /*allowOptionalChain*/ true);
|
||||
}
|
||||
|
||||
function parseSuperExpression(): MemberExpression {
|
||||
@@ -4590,18 +4595,70 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseMemberExpressionRest(expression: LeftHandSideExpression): MemberExpression {
|
||||
function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() {
|
||||
nextToken();
|
||||
return tokenIsIdentifierOrKeyword(token())
|
||||
|| token() === SyntaxKind.OpenBracketToken
|
||||
|| isTemplateStartOfTaggedTemplate();
|
||||
}
|
||||
|
||||
function isStartOfOptionalPropertyOrElementAccessChain() {
|
||||
return token() === SyntaxKind.QuestionDotToken
|
||||
&& lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate);
|
||||
}
|
||||
|
||||
function parsePropertyAccessExpressionRest(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) {
|
||||
const propertyAccess = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, expression.pos);
|
||||
propertyAccess.expression = expression;
|
||||
propertyAccess.questionDotToken = questionDotToken;
|
||||
propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
|
||||
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
|
||||
propertyAccess.flags |= NodeFlags.OptionalChain;
|
||||
}
|
||||
return finishNode(propertyAccess);
|
||||
}
|
||||
|
||||
function parseElementAccessExpressionRest(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) {
|
||||
const indexedAccess = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, expression.pos);
|
||||
indexedAccess.expression = expression;
|
||||
indexedAccess.questionDotToken = questionDotToken;
|
||||
|
||||
if (token() === SyntaxKind.CloseBracketToken) {
|
||||
indexedAccess.argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument);
|
||||
}
|
||||
else {
|
||||
const argument = allowInAnd(parseExpression);
|
||||
if (isStringOrNumericLiteralLike(argument)) {
|
||||
argument.text = internIdentifier(argument.text);
|
||||
}
|
||||
indexedAccess.argumentExpression = argument;
|
||||
}
|
||||
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
|
||||
indexedAccess.flags |= NodeFlags.OptionalChain;
|
||||
}
|
||||
return finishNode(indexedAccess);
|
||||
}
|
||||
|
||||
function parseMemberExpressionRest(expression: LeftHandSideExpression, allowOptionalChain: boolean): MemberExpression {
|
||||
while (true) {
|
||||
const dotToken = parseOptionalToken(SyntaxKind.DotToken);
|
||||
if (dotToken) {
|
||||
const propertyAccess = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, expression.pos);
|
||||
propertyAccess.expression = expression;
|
||||
propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
|
||||
expression = finishNode(propertyAccess);
|
||||
let questionDotToken: QuestionDotToken | undefined;
|
||||
let isPropertyAccess = false;
|
||||
if (allowOptionalChain && isStartOfOptionalPropertyOrElementAccessChain()) {
|
||||
questionDotToken = parseExpectedToken(SyntaxKind.QuestionDotToken);
|
||||
isPropertyAccess = tokenIsIdentifierOrKeyword(token());
|
||||
}
|
||||
else {
|
||||
isPropertyAccess = parseOptional(SyntaxKind.DotToken);
|
||||
}
|
||||
|
||||
if (isPropertyAccess) {
|
||||
expression = parsePropertyAccessExpressionRest(expression, questionDotToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
|
||||
if (!questionDotToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
|
||||
nextToken();
|
||||
const nonNullExpression = <NonNullExpression>createNode(SyntaxKind.NonNullExpression, expression.pos);
|
||||
nonNullExpression.expression = expression;
|
||||
@@ -4610,28 +4667,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
// when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
|
||||
if (!inDecoratorContext() && parseOptional(SyntaxKind.OpenBracketToken)) {
|
||||
const indexedAccess = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, expression.pos);
|
||||
indexedAccess.expression = expression;
|
||||
|
||||
if (token() === SyntaxKind.CloseBracketToken) {
|
||||
indexedAccess.argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument);
|
||||
}
|
||||
else {
|
||||
const argument = allowInAnd(parseExpression);
|
||||
if (isStringOrNumericLiteralLike(argument)) {
|
||||
argument.text = internIdentifier(argument.text);
|
||||
}
|
||||
indexedAccess.argumentExpression = argument;
|
||||
}
|
||||
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
expression = finishNode(indexedAccess);
|
||||
if ((questionDotToken || !inDecoratorContext()) && parseOptional(SyntaxKind.OpenBracketToken)) {
|
||||
expression = parseElementAccessExpressionRest(expression, questionDotToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isTemplateStartOfTaggedTemplate()) {
|
||||
expression = parseTaggedTemplateRest(expression, /*typeArguments*/ undefined);
|
||||
expression = parseTaggedTemplateRest(expression, questionDotToken, /*typeArguments*/ undefined);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4643,19 +4685,25 @@ namespace ts {
|
||||
return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead;
|
||||
}
|
||||
|
||||
function parseTaggedTemplateRest(tag: LeftHandSideExpression, typeArguments: NodeArray<TypeNode> | undefined) {
|
||||
function parseTaggedTemplateRest(tag: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray<TypeNode> | undefined) {
|
||||
const tagExpression = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, tag.pos);
|
||||
tagExpression.tag = tag;
|
||||
tagExpression.questionDotToken = questionDotToken;
|
||||
tagExpression.typeArguments = typeArguments;
|
||||
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
? <NoSubstitutionTemplateLiteral>parseLiteralNode()
|
||||
: parseTemplateExpression();
|
||||
if (questionDotToken || tag.flags & NodeFlags.OptionalChain) {
|
||||
tagExpression.flags |= NodeFlags.OptionalChain;
|
||||
}
|
||||
return finishNode(tagExpression);
|
||||
}
|
||||
|
||||
function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression {
|
||||
while (true) {
|
||||
expression = parseMemberExpressionRest(expression);
|
||||
expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ true);
|
||||
const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken);
|
||||
|
||||
// handle 'foo<<T>()'
|
||||
if (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken) {
|
||||
// See if this is the start of a generic invocation. If so, consume it and
|
||||
@@ -4663,32 +4711,47 @@ namespace ts {
|
||||
// part of an arithmetic expression. Break out so we consume it higher in the
|
||||
// stack.
|
||||
const typeArguments = tryParse(parseTypeArgumentsInExpression);
|
||||
if (!typeArguments) {
|
||||
return expression;
|
||||
}
|
||||
if (typeArguments) {
|
||||
if (isTemplateStartOfTaggedTemplate()) {
|
||||
expression = parseTaggedTemplateRest(expression, questionDotToken, typeArguments);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isTemplateStartOfTaggedTemplate()) {
|
||||
expression = parseTaggedTemplateRest(expression, typeArguments);
|
||||
const callExpr = <CallExpression>createNode(SyntaxKind.CallExpression, expression.pos);
|
||||
callExpr.expression = expression;
|
||||
callExpr.questionDotToken = questionDotToken;
|
||||
callExpr.typeArguments = typeArguments;
|
||||
callExpr.arguments = parseArgumentList();
|
||||
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
|
||||
callExpr.flags |= NodeFlags.OptionalChain;
|
||||
}
|
||||
expression = finishNode(callExpr);
|
||||
continue;
|
||||
}
|
||||
|
||||
const callExpr = <CallExpression>createNode(SyntaxKind.CallExpression, expression.pos);
|
||||
callExpr.expression = expression;
|
||||
callExpr.typeArguments = typeArguments;
|
||||
callExpr.arguments = parseArgumentList();
|
||||
expression = finishNode(callExpr);
|
||||
continue;
|
||||
}
|
||||
else if (token() === SyntaxKind.OpenParenToken) {
|
||||
const callExpr = <CallExpression>createNode(SyntaxKind.CallExpression, expression.pos);
|
||||
callExpr.expression = expression;
|
||||
callExpr.questionDotToken = questionDotToken;
|
||||
callExpr.arguments = parseArgumentList();
|
||||
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
|
||||
callExpr.flags |= NodeFlags.OptionalChain;
|
||||
}
|
||||
expression = finishNode(callExpr);
|
||||
continue;
|
||||
}
|
||||
|
||||
return expression;
|
||||
if (questionDotToken) {
|
||||
// We failed to parse anything, so report a missing identifier here.
|
||||
const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos) as PropertyAccessExpression;
|
||||
propertyAccess.expression = expression;
|
||||
propertyAccess.questionDotToken = questionDotToken;
|
||||
propertyAccess.name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected);
|
||||
propertyAccess.flags |= NodeFlags.OptionalChain;
|
||||
expression = finishNode(propertyAccess);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
function parseArgumentList() {
|
||||
@@ -4957,12 +5020,12 @@ namespace ts {
|
||||
let expression: MemberExpression = parsePrimaryExpression();
|
||||
let typeArguments;
|
||||
while (true) {
|
||||
expression = parseMemberExpressionRest(expression);
|
||||
expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ false);
|
||||
typeArguments = tryParse(parseTypeArgumentsInExpression);
|
||||
if (isTemplateStartOfTaggedTemplate()) {
|
||||
Debug.assert(!!typeArguments,
|
||||
"Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'");
|
||||
expression = parseTaggedTemplateRest(expression, typeArguments);
|
||||
expression = parseTaggedTemplateRest(expression, /*optionalChain*/ undefined, typeArguments);
|
||||
typeArguments = undefined;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -184,6 +184,7 @@ namespace ts {
|
||||
"&&": SyntaxKind.AmpersandAmpersandToken,
|
||||
"||": SyntaxKind.BarBarToken,
|
||||
"?": SyntaxKind.QuestionToken,
|
||||
"?.": SyntaxKind.QuestionDotToken,
|
||||
":": SyntaxKind.ColonToken,
|
||||
"=": SyntaxKind.EqualsToken,
|
||||
"+=": SyntaxKind.PlusEqualsToken,
|
||||
@@ -1829,6 +1830,10 @@ namespace ts {
|
||||
return token = SyntaxKind.GreaterThanToken;
|
||||
case CharacterCodes.question:
|
||||
pos++;
|
||||
if (text.charCodeAt(pos) === CharacterCodes.dot && !isDigit(text.charCodeAt(pos + 1))) {
|
||||
pos++;
|
||||
return token = SyntaxKind.QuestionDotToken;
|
||||
}
|
||||
return token = SyntaxKind.QuestionToken;
|
||||
case CharacterCodes.openBracket:
|
||||
pos++;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformESNext(context: TransformationContext) {
|
||||
const {
|
||||
hoistVariableDeclaration
|
||||
} = context;
|
||||
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@@ -16,9 +20,157 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
const updated = visitOptionalExpression(node as OptionalChain, /*captureThisArg*/ false);
|
||||
Debug.assertNotNode(updated, isSyntheticReference);
|
||||
return updated;
|
||||
}
|
||||
// falls through
|
||||
default:
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function flattenChain(chain: OptionalChain) {
|
||||
const links: OptionalChain[] = [chain];
|
||||
while (!chain.questionDotToken && !isTaggedTemplateExpression(chain)) {
|
||||
chain = cast(chain.expression, isOptionalChain);
|
||||
links.unshift(chain);
|
||||
}
|
||||
return { expression: chain.expression, chain: links };
|
||||
}
|
||||
|
||||
function visitNonOptionalParenthesizedExpression(node: ParenthesizedExpression, captureThisArg: boolean): Expression {
|
||||
const expression = visitNonOptionalExpression(node.expression, captureThisArg);
|
||||
if (isSyntheticReference(expression)) {
|
||||
// `(a.b)` -> { expression `((_a = a).b)`, thisArg: `_a` }
|
||||
// `(a[b])` -> { expression `((_a = a)[b])`, thisArg: `_a` }
|
||||
return createSyntheticReferenceExpression(updateParen(node, expression.expression), expression.thisArg);
|
||||
}
|
||||
return updateParen(node, expression);
|
||||
}
|
||||
|
||||
function visitNonOptionalPropertyAccessExpression(node: PropertyAccessExpression, captureThisArg: boolean): Expression {
|
||||
if (isOptionalChain(node)) {
|
||||
// If `node` is an optional chain, then it is the outermost chain of an optional expression.
|
||||
return visitOptionalExpression(node, captureThisArg);
|
||||
}
|
||||
|
||||
let expression = visitNode(node.expression, visitor, isExpression);
|
||||
Debug.assertNotNode(expression, isSyntheticReference);
|
||||
|
||||
let thisArg: Expression | undefined;
|
||||
if (captureThisArg) {
|
||||
// `a.b` -> { expression: `(_a = a).b`, thisArg: `_a` }
|
||||
thisArg = createTempVariable(hoistVariableDeclaration);
|
||||
expression = createParen(createAssignment(thisArg, expression));
|
||||
}
|
||||
|
||||
expression = updatePropertyAccess(node, expression, visitNode(node.name, visitor, isIdentifier));
|
||||
return thisArg ? createSyntheticReferenceExpression(expression, thisArg) : expression;
|
||||
}
|
||||
|
||||
function visitNonOptionalElementAccessExpression(node: ElementAccessExpression, captureThisArg: boolean): Expression {
|
||||
if (isOptionalChain(node)) {
|
||||
// If `node` is an optional chain, then it is the outermost chain of an optional expression.
|
||||
return visitOptionalExpression(node, captureThisArg);
|
||||
}
|
||||
|
||||
let expression = visitNode(node.expression, visitor, isExpression);
|
||||
Debug.assertNotNode(expression, isSyntheticReference);
|
||||
|
||||
let thisArg: Expression | undefined;
|
||||
if (captureThisArg) {
|
||||
// `a[b]` -> { expression: `(_a = a)[b]`, thisArg: `_a` }
|
||||
thisArg = createTempVariable(hoistVariableDeclaration);
|
||||
expression = createParen(createAssignment(thisArg, expression));
|
||||
}
|
||||
|
||||
expression = updateElementAccess(node, expression, visitNode(node.argumentExpression, visitor, isExpression));
|
||||
return thisArg ? createSyntheticReferenceExpression(expression, thisArg) : expression;
|
||||
}
|
||||
|
||||
function visitNonOptionalCallExpression(node: CallExpression, captureThisArg: boolean): Expression {
|
||||
if (isOptionalChain(node)) {
|
||||
// If `node` is an optional chain, then it is the outermost chain of an optional expression.
|
||||
return visitOptionalExpression(node, captureThisArg);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitNonOptionalExpression(node: Expression, captureThisArg: boolean): Expression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression: return visitNonOptionalParenthesizedExpression(node as ParenthesizedExpression, captureThisArg);
|
||||
case SyntaxKind.PropertyAccessExpression: return visitNonOptionalPropertyAccessExpression(node as PropertyAccessExpression, captureThisArg);
|
||||
case SyntaxKind.ElementAccessExpression: return visitNonOptionalElementAccessExpression(node as ElementAccessExpression, captureThisArg);
|
||||
case SyntaxKind.CallExpression: return visitNonOptionalCallExpression(node as CallExpression, captureThisArg);
|
||||
default: return visitNode(node, visitor, isExpression);
|
||||
}
|
||||
}
|
||||
|
||||
function visitOptionalExpression(node: OptionalChain, captureThisArg: boolean): Expression {
|
||||
const { expression, chain } = flattenChain(node);
|
||||
const left = visitNonOptionalExpression(expression, isCallChain(chain[0]));
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
const leftThisArg = isSyntheticReference(left) ? left.thisArg : undefined;
|
||||
const leftExpression = isSyntheticReference(left) ? left.expression : left;
|
||||
let rightExpression: Expression = temp;
|
||||
let thisArg: Expression | undefined;
|
||||
for (let i = 0; i < chain.length; i++) {
|
||||
const segment = chain[i];
|
||||
switch (segment.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
if (i === chain.length - 1 && captureThisArg) {
|
||||
thisArg = createTempVariable(hoistVariableDeclaration);
|
||||
rightExpression = createParen(createAssignment(thisArg, rightExpression));
|
||||
}
|
||||
rightExpression = createPropertyAccess(
|
||||
rightExpression,
|
||||
visitNode(segment.name, visitor, isIdentifier)
|
||||
);
|
||||
break;
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
if (i === chain.length - 1 && captureThisArg) {
|
||||
thisArg = createTempVariable(hoistVariableDeclaration);
|
||||
rightExpression = createParen(createAssignment(thisArg, rightExpression));
|
||||
}
|
||||
rightExpression = createElementAccess(
|
||||
rightExpression,
|
||||
visitNode(segment.argumentExpression, visitor, isExpression)
|
||||
);
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
if (i === 0 && leftThisArg) {
|
||||
rightExpression = createFunctionCall(
|
||||
rightExpression,
|
||||
leftThisArg,
|
||||
visitNodes(segment.arguments, visitor, isExpression)
|
||||
);
|
||||
}
|
||||
else {
|
||||
rightExpression = createCall(
|
||||
rightExpression,
|
||||
/*typeArguments*/ undefined,
|
||||
visitNodes(segment.arguments, visitor, isExpression)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
setOriginalNode(rightExpression, segment);
|
||||
}
|
||||
|
||||
const target = createConditional(
|
||||
createLogicalOr(
|
||||
createStrictEquality(createAssignment(temp, leftExpression), createNull()),
|
||||
createStrictEquality(temp, createVoidZero())
|
||||
),
|
||||
createVoidZero(),
|
||||
rightExpression
|
||||
);
|
||||
return thisArg ? createSyntheticReferenceExpression(target, thisArg) : target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+85
-21
@@ -152,6 +152,7 @@ namespace ts {
|
||||
DotDotDotToken,
|
||||
SemicolonToken,
|
||||
CommaToken,
|
||||
QuestionDotToken,
|
||||
LessThanToken,
|
||||
LessThanSlashToken,
|
||||
GreaterThanToken,
|
||||
@@ -485,6 +486,7 @@ namespace ts {
|
||||
CommaListExpression,
|
||||
MergeDeclarationMarker,
|
||||
EndOfDeclarationMarker,
|
||||
SyntheticReferenceExpression,
|
||||
|
||||
// Enum value count
|
||||
Count,
|
||||
@@ -532,20 +534,21 @@ namespace ts {
|
||||
NestedNamespace = 1 << 2, // Namespace declaration
|
||||
Synthesized = 1 << 3, // Node was synthesized during transformation
|
||||
Namespace = 1 << 4, // Namespace declaration
|
||||
ExportContext = 1 << 5, // Export context (initialized by binding)
|
||||
ContainsThis = 1 << 6, // Interface contains references to "this"
|
||||
HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding)
|
||||
HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding)
|
||||
GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope
|
||||
HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding)
|
||||
DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed
|
||||
YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator
|
||||
DecoratorContext = 1 << 13, // If node was parsed as part of a decorator
|
||||
AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function
|
||||
ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node
|
||||
JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
|
||||
OptionalChain = 1 << 5, // Chained MemberExpression rooted to a pseudo-OptionalExpression
|
||||
ExportContext = 1 << 6, // Export context (initialized by binding)
|
||||
ContainsThis = 1 << 7, // Interface contains references to "this"
|
||||
HasImplicitReturn = 1 << 8, // If function implicitly returns on one of codepaths (initialized by binding)
|
||||
HasExplicitReturn = 1 << 9, // If function has explicit reachable return on one of codepaths (initialized by binding)
|
||||
GlobalAugmentation = 1 << 10, // Set if module declaration is an augmentation for the global scope
|
||||
HasAsyncFunctions = 1 << 11, // If the file has async functions (initialized by binding)
|
||||
DisallowInContext = 1 << 12, // If node was parsed in a context where 'in-expressions' are not allowed
|
||||
YieldContext = 1 << 13, // If node was parsed in the 'yield' context created when parsing a generator
|
||||
DecoratorContext = 1 << 14, // If node was parsed as part of a decorator
|
||||
AwaitContext = 1 << 15, // If node was parsed in the 'await' context created when parsing an async function
|
||||
ThisNodeHasError = 1 << 16, // If the parser encountered an error when parsing the code that created this node
|
||||
JavaScriptFile = 1 << 17, // If node was parsed in a JavaScript
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 18, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 19, // If we've computed data from children and cached it in this node
|
||||
|
||||
// These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid
|
||||
// walking the tree if the flags are not set. However, these flags are just a approximation
|
||||
@@ -556,13 +559,13 @@ namespace ts {
|
||||
// removal, it is likely that users will add the import anyway.
|
||||
// The advantage of this approach is its simplicity. For the case of batch compilation,
|
||||
// we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
|
||||
/* @internal */ PossiblyContainsDynamicImport = 1 << 19,
|
||||
/* @internal */ PossiblyContainsImportMeta = 1 << 20,
|
||||
/* @internal */ PossiblyContainsDynamicImport = 1 << 20,
|
||||
/* @internal */ PossiblyContainsImportMeta = 1 << 21,
|
||||
|
||||
JSDoc = 1 << 21, // If node was parsed inside jsdoc
|
||||
/* @internal */ Ambient = 1 << 22, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
|
||||
/* @internal */ InWithStatement = 1 << 23, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
JsonFile = 1 << 24, // If node was parsed in a Json
|
||||
JSDoc = 1 << 22, // If node was parsed inside jsdoc
|
||||
/* @internal */ Ambient = 1 << 23, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
|
||||
/* @internal */ InWithStatement = 1 << 24, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
JsonFile = 1 << 25, // If node was parsed in a Json
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
@@ -732,8 +735,10 @@ namespace ts {
|
||||
kind: TKind;
|
||||
}
|
||||
|
||||
export type DotToken = Token<SyntaxKind.DotToken>;
|
||||
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
export type QuestionDotToken = Token<SyntaxKind.QuestionDotToken>;
|
||||
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
export type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
@@ -1803,9 +1808,19 @@ namespace ts {
|
||||
export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration {
|
||||
kind: SyntaxKind.PropertyAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
name: Identifier;
|
||||
}
|
||||
|
||||
export interface PropertyAccessChain extends PropertyAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface PropertyAccessChainRoot extends PropertyAccessChain {
|
||||
questionDotToken: QuestionDotToken;
|
||||
}
|
||||
|
||||
export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -1819,9 +1834,19 @@ namespace ts {
|
||||
export interface ElementAccessExpression extends MemberExpression {
|
||||
kind: SyntaxKind.ElementAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
argumentExpression: Expression;
|
||||
}
|
||||
|
||||
export interface ElementAccessChain extends ElementAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface ElementAccessChainRoot extends ElementAccessChain {
|
||||
questionDotToken: QuestionDotToken;
|
||||
}
|
||||
|
||||
export interface SuperElementAccessExpression extends ElementAccessExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -1832,10 +1857,33 @@ namespace ts {
|
||||
export interface CallExpression extends LeftHandSideExpression, Declaration {
|
||||
kind: SyntaxKind.CallExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
arguments: NodeArray<Expression>;
|
||||
}
|
||||
|
||||
export interface CallChain extends CallExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface CallChainRoot extends CallChain {
|
||||
questionDotToken: QuestionDotToken;
|
||||
}
|
||||
|
||||
export type OptionalChain =
|
||||
| PropertyAccessChain
|
||||
| ElementAccessChain
|
||||
| CallChain
|
||||
;
|
||||
|
||||
/* @internal */
|
||||
export type OptionalChainRoot =
|
||||
| PropertyAccessChainRoot
|
||||
| ElementAccessChainRoot
|
||||
| CallChainRoot
|
||||
;
|
||||
|
||||
/** @internal */
|
||||
export type BindableObjectDefinePropertyCall = CallExpression & { arguments: { 0: EntityNameExpression, 1: StringLiteralLike | NumericLiteral, 2: ObjectLiteralExpression } };
|
||||
|
||||
@@ -1866,6 +1914,7 @@ namespace ts {
|
||||
tag: LeftHandSideExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
template: TemplateLiteral;
|
||||
/*@internal*/ questionDotToken?: QuestionDotToken; // NOTE: Invalid syntax, only used to report a grammar error.
|
||||
}
|
||||
|
||||
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement;
|
||||
@@ -2033,6 +2082,13 @@ namespace ts {
|
||||
kind: SyntaxKind.MergeDeclarationMarker;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface SyntheticReferenceExpression extends LeftHandSideExpression {
|
||||
kind: SyntaxKind.SyntheticReferenceExpression;
|
||||
expression: Expression;
|
||||
thisArg: Expression;
|
||||
}
|
||||
|
||||
export interface EmptyStatement extends Statement {
|
||||
kind: SyntaxKind.EmptyStatement;
|
||||
}
|
||||
@@ -2603,8 +2659,9 @@ namespace ts {
|
||||
AfterFinally = 1 << 13, // Injected edge that links post-finally flow with the rest of the graph
|
||||
/** @internal */
|
||||
Cached = 1 << 14, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant
|
||||
|
||||
Label = BranchLabel | LoopLabel,
|
||||
Condition = TrueCondition | FalseCondition
|
||||
Condition = TrueCondition | FalseCondition,
|
||||
}
|
||||
|
||||
export type FlowNode =
|
||||
@@ -3209,6 +3266,8 @@ namespace ts {
|
||||
/* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type;
|
||||
getNullableType(type: Type, flags: TypeFlags): Type;
|
||||
getNonNullableType(type: Type): Type;
|
||||
/* @internal */ getNonOptionalType(type: Type): Type;
|
||||
/* @internal */ isNullableType(type: Type): boolean;
|
||||
getTypeArguments(type: TypeReference): readonly Type[];
|
||||
|
||||
// TODO: GH#18217 `xToDeclaration` calls are frequently asserted as defined.
|
||||
@@ -3329,6 +3388,7 @@ namespace ts {
|
||||
/* @internal */ getNullType(): Type;
|
||||
/* @internal */ getESSymbolType(): Type;
|
||||
/* @internal */ getNeverType(): Type;
|
||||
/* @internal */ getOptionalType(): Type;
|
||||
/* @internal */ getUnionType(types: Type[], subtypeReduction?: UnionReduction): Type;
|
||||
/* @internal */ createArrayType(elementType: Type): Type;
|
||||
/* @internal */ getElementTypeOfArrayType(arrayType: Type): Type | undefined;
|
||||
@@ -4590,6 +4650,8 @@ namespace ts {
|
||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||
/* @internal */
|
||||
instantiations?: Map<Signature>; // Generic signature instantiation cache
|
||||
/* @internal */
|
||||
isOptionalCall?: boolean;
|
||||
}
|
||||
|
||||
export const enum IndexKind {
|
||||
@@ -6032,6 +6094,8 @@ namespace ts {
|
||||
getColumn(): number;
|
||||
getIndent(): number;
|
||||
isAtStartOfLine(): boolean;
|
||||
hasTrailingComment(): boolean;
|
||||
hasTrailingWhitespace(): boolean;
|
||||
getTextPosWithWriteLine?(): number;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace ts {
|
||||
|
||||
function createSingleLineStringWriter(): EmitTextWriter {
|
||||
let str = "";
|
||||
|
||||
const writeText: (text: string) => void = text => str += text;
|
||||
return {
|
||||
getText: () => str,
|
||||
@@ -79,6 +78,8 @@ namespace ts {
|
||||
getColumn: () => 0,
|
||||
getIndent: () => 0,
|
||||
isAtStartOfLine: () => false,
|
||||
hasTrailingComment: () => false,
|
||||
hasTrailingWhitespace: () => !!str.length && isWhiteSpaceLike(str.charCodeAt(str.length - 1)),
|
||||
|
||||
// Completely ignore indentation for string writers. And map newlines to
|
||||
// a single space.
|
||||
@@ -3349,6 +3350,7 @@ namespace ts {
|
||||
let lineStart: boolean;
|
||||
let lineCount: number;
|
||||
let linePos: number;
|
||||
let hasTrailingComment = false;
|
||||
|
||||
function updateLineCountAndPosFor(s: string) {
|
||||
const lineStartsOfS = computeLineStarts(s);
|
||||
@@ -3362,7 +3364,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function write(s: string) {
|
||||
function writeText(s: string) {
|
||||
if (s && s.length) {
|
||||
if (lineStart) {
|
||||
s = getIndentString(indent) + s;
|
||||
@@ -3373,18 +3375,30 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function write(s: string) {
|
||||
if (s) hasTrailingComment = false;
|
||||
writeText(s);
|
||||
}
|
||||
|
||||
function writeComment(s: string) {
|
||||
if (s) hasTrailingComment = true;
|
||||
writeText(s);
|
||||
}
|
||||
|
||||
function reset(): void {
|
||||
output = "";
|
||||
indent = 0;
|
||||
lineStart = true;
|
||||
lineCount = 0;
|
||||
linePos = 0;
|
||||
hasTrailingComment = false;
|
||||
}
|
||||
|
||||
function rawWrite(s: string) {
|
||||
if (s !== undefined) {
|
||||
output += s;
|
||||
updateLineCountAndPosFor(s);
|
||||
hasTrailingComment = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3400,6 +3414,7 @@ namespace ts {
|
||||
lineCount++;
|
||||
linePos = output.length;
|
||||
lineStart = true;
|
||||
hasTrailingComment = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3422,6 +3437,8 @@ namespace ts {
|
||||
getColumn: () => lineStart ? indent * getIndentSize() : output.length - linePos,
|
||||
getText: () => output,
|
||||
isAtStartOfLine: () => lineStart,
|
||||
hasTrailingComment: () => hasTrailingComment,
|
||||
hasTrailingWhitespace: () => !!output.length && isWhiteSpaceLike(output.charCodeAt(output.length - 1)),
|
||||
clear: reset,
|
||||
reportInaccessibleThisError: noop,
|
||||
reportPrivateInBaseOfClassExpression: noop,
|
||||
@@ -3436,7 +3453,7 @@ namespace ts {
|
||||
writeStringLiteral: write,
|
||||
writeSymbol: (s, _) => write(s),
|
||||
writeTrailingSemicolon: write,
|
||||
writeComment: write,
|
||||
writeComment,
|
||||
getTextPosWithWriteLine
|
||||
};
|
||||
}
|
||||
@@ -4792,6 +4809,10 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getDotOrQuestionDotToken(node: PropertyAccessExpression) {
|
||||
return node.questionDotToken || createNode(SyntaxKind.DotToken, node.expression.end, node.name.pos) as DotToken;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
@@ -5807,14 +5828,32 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression;
|
||||
}
|
||||
|
||||
export function isPropertyAccessChain(node: Node): node is PropertyAccessChain {
|
||||
return isPropertyAccessExpression(node) && !!(node.flags & NodeFlags.OptionalChain);
|
||||
}
|
||||
|
||||
export function isElementAccessExpression(node: Node): node is ElementAccessExpression {
|
||||
return node.kind === SyntaxKind.ElementAccessExpression;
|
||||
}
|
||||
|
||||
export function isElementAccessChain(node: Node): node is ElementAccessChain {
|
||||
return isElementAccessExpression(node) && !!(node.flags & NodeFlags.OptionalChain);
|
||||
}
|
||||
|
||||
export function isCallExpression(node: Node): node is CallExpression {
|
||||
return node.kind === SyntaxKind.CallExpression;
|
||||
}
|
||||
|
||||
export function isCallChain(node: Node): node is CallChain {
|
||||
return isCallExpression(node) && !!(node.flags & NodeFlags.OptionalChain);
|
||||
}
|
||||
|
||||
export function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain {
|
||||
return isPropertyAccessChain(node)
|
||||
|| isElementAccessChain(node)
|
||||
|| isCallChain(node);
|
||||
}
|
||||
|
||||
export function isNewExpression(node: Node): node is NewExpression {
|
||||
return node.kind === SyntaxKind.NewExpression;
|
||||
}
|
||||
@@ -6823,6 +6862,11 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.NotEmittedStatement;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isSyntheticReference(node: Node): node is SyntheticReferenceExpression {
|
||||
return node.kind === SyntaxKind.SyntheticReferenceExpression;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isNotEmittedOrPartiallyEmittedNode(node: Node): node is NotEmittedStatement | PartiallyEmittedExpression {
|
||||
return isNotEmittedStatement(node)
|
||||
@@ -7127,6 +7171,11 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.GetAccessor;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isOptionalChainRoot(node: Node): node is OptionalChainRoot {
|
||||
return isOptionalChain(node) && !!node.questionDotToken;
|
||||
}
|
||||
|
||||
/** True if has jsdoc nodes attached to it. */
|
||||
/* @internal */
|
||||
// TODO: GH#19856 Would like to return `node is Node & { jsDoc: JSDoc[] }` but it causes long compile times
|
||||
|
||||
@@ -456,16 +456,35 @@ namespace ts {
|
||||
nodesVisitor((<ObjectLiteralExpression>node).properties, visitor, isObjectLiteralElementLike));
|
||||
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
return updatePropertyAccessChain(<PropertyAccessChain>node,
|
||||
visitNode((<PropertyAccessChain>node).expression, visitor, isExpression),
|
||||
visitNode((<PropertyAccessChain>node).questionDotToken, visitor, isToken),
|
||||
visitNode((<PropertyAccessChain>node).name, visitor, isIdentifier));
|
||||
}
|
||||
return updatePropertyAccess(<PropertyAccessExpression>node,
|
||||
visitNode((<PropertyAccessExpression>node).expression, visitor, isExpression),
|
||||
visitNode((<PropertyAccessExpression>node).name, visitor, isIdentifier));
|
||||
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
return updateElementAccessChain(<ElementAccessChain>node,
|
||||
visitNode((<ElementAccessChain>node).expression, visitor, isExpression),
|
||||
visitNode((<ElementAccessChain>node).questionDotToken, visitor, isToken),
|
||||
visitNode((<ElementAccessChain>node).argumentExpression, visitor, isExpression));
|
||||
}
|
||||
return updateElementAccess(<ElementAccessExpression>node,
|
||||
visitNode((<ElementAccessExpression>node).expression, visitor, isExpression),
|
||||
visitNode((<ElementAccessExpression>node).argumentExpression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
if (node.flags & NodeFlags.OptionalChain) {
|
||||
return updateCallChain(<CallChain>node,
|
||||
visitNode((<CallChain>node).expression, visitor, isExpression),
|
||||
visitNode((<CallChain>node).questionDotToken, visitor, isToken),
|
||||
nodesVisitor((<CallChain>node).typeArguments, visitor, isTypeNode),
|
||||
nodesVisitor((<CallChain>node).arguments, visitor, isExpression));
|
||||
}
|
||||
return updateCall(<CallExpression>node,
|
||||
visitNode((<CallExpression>node).expression, visitor, isExpression),
|
||||
nodesVisitor((<CallExpression>node).typeArguments, visitor, isTypeNode),
|
||||
|
||||
+93
-29
@@ -11,28 +11,52 @@ namespace ts.Completions {
|
||||
}
|
||||
export type Log = (message: string) => void;
|
||||
|
||||
const enum SymbolOriginInfoKind { ThisType, SymbolMemberNoExport, SymbolMemberExport, Export, Promise }
|
||||
type SymbolOriginInfo = { kind: SymbolOriginInfoKind.ThisType } | { kind: SymbolOriginInfoKind.Promise } | { kind: SymbolOriginInfoKind.SymbolMemberNoExport } | SymbolOriginInfoExport;
|
||||
interface SymbolOriginInfoExport {
|
||||
kind: SymbolOriginInfoKind.SymbolMemberExport | SymbolOriginInfoKind.Export;
|
||||
const enum SymbolOriginInfoKind {
|
||||
ThisType = 1 << 0,
|
||||
SymbolMember = 1 << 1,
|
||||
Export = 1 << 2,
|
||||
Promise = 1 << 3,
|
||||
Nullable = 1 << 4,
|
||||
|
||||
SymbolMemberNoExport = SymbolMember,
|
||||
SymbolMemberExport = SymbolMember | Export,
|
||||
}
|
||||
|
||||
interface SymbolOriginInfo {
|
||||
kind: SymbolOriginInfoKind;
|
||||
}
|
||||
|
||||
interface SymbolOriginInfoExport extends SymbolOriginInfo {
|
||||
kind: SymbolOriginInfoKind;
|
||||
moduleSymbol: Symbol;
|
||||
isDefaultExport: boolean;
|
||||
}
|
||||
|
||||
function originIsThisType(origin: SymbolOriginInfo): boolean {
|
||||
return !!(origin.kind & SymbolOriginInfoKind.ThisType);
|
||||
}
|
||||
|
||||
function originIsSymbolMember(origin: SymbolOriginInfo): boolean {
|
||||
return origin.kind === SymbolOriginInfoKind.SymbolMemberExport || origin.kind === SymbolOriginInfoKind.SymbolMemberNoExport;
|
||||
return !!(origin.kind & SymbolOriginInfoKind.SymbolMember);
|
||||
}
|
||||
|
||||
function originIsExport(origin: SymbolOriginInfo): origin is SymbolOriginInfoExport {
|
||||
return origin.kind === SymbolOriginInfoKind.SymbolMemberExport || origin.kind === SymbolOriginInfoKind.Export;
|
||||
return !!(origin.kind & SymbolOriginInfoKind.Export);
|
||||
}
|
||||
|
||||
function originIsPromise(origin: SymbolOriginInfo): boolean {
|
||||
return origin.kind === SymbolOriginInfoKind.Promise;
|
||||
return !!(origin.kind & SymbolOriginInfoKind.Promise);
|
||||
}
|
||||
|
||||
function originIsNullableMember(origin: SymbolOriginInfo): boolean {
|
||||
return !!(origin.kind & SymbolOriginInfoKind.Nullable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map from symbol id -> SymbolOriginInfo.
|
||||
* Only populated for symbols that come from other modules.
|
||||
*/
|
||||
type SymbolOriginInfoMap = (SymbolOriginInfo | undefined)[];
|
||||
type SymbolOriginInfoMap = (SymbolOriginInfo | SymbolOriginInfoExport | undefined)[];
|
||||
|
||||
type SymbolSortTextMap = (SortText | undefined)[];
|
||||
|
||||
@@ -314,14 +338,26 @@ namespace ts.Completions {
|
||||
): CompletionEntry | undefined {
|
||||
let insertText: string | undefined;
|
||||
let replacementSpan: TextSpan | undefined;
|
||||
if (origin && origin.kind === SymbolOriginInfoKind.ThisType) {
|
||||
insertText = needsConvertPropertyAccess ? `this[${quote(name, preferences)}]` : `this.${name}`;
|
||||
const insertQuestionDot = origin && originIsNullableMember(origin);
|
||||
const useBraces = origin && originIsSymbolMember(origin) || needsConvertPropertyAccess;
|
||||
if (origin && originIsThisType(origin)) {
|
||||
insertText = needsConvertPropertyAccess
|
||||
? `this${insertQuestionDot ? "?." : ""}[${quote(name, preferences)}]`
|
||||
: `this${insertQuestionDot ? "?." : "."}${name}`;
|
||||
}
|
||||
// We should only have needsConvertPropertyAccess if there's a property access to convert. But see #21790.
|
||||
// Somehow there was a global with a non-identifier name. Hopefully someone will complain about getting a "foo bar" global completion and provide a repro.
|
||||
else if ((origin && originIsSymbolMember(origin) || needsConvertPropertyAccess) && propertyAccessToConvert) {
|
||||
insertText = needsConvertPropertyAccess ? `[${quote(name, preferences)}]` : `[${name}]`;
|
||||
const dot = findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile)!;
|
||||
else if ((useBraces || insertQuestionDot) && propertyAccessToConvert) {
|
||||
insertText = useBraces ? needsConvertPropertyAccess ? `[${quote(name, preferences)}]` : `[${name}]` : name;
|
||||
if (insertQuestionDot || propertyAccessToConvert.questionDotToken) {
|
||||
insertText = `?.${insertText}`;
|
||||
}
|
||||
|
||||
const dot = findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile) ||
|
||||
findChildOfKind(propertyAccessToConvert, SyntaxKind.QuestionDotToken, sourceFile);
|
||||
if (!dot) {
|
||||
return undefined;
|
||||
}
|
||||
// If the text after the '.' starts with this name, write over it. Else, add new text.
|
||||
const end = startsWith(name, propertyAccessToConvert.name.text) ? propertyAccessToConvert.name.end : dot.end;
|
||||
replacementSpan = createTextSpanFromBounds(dot.getStart(sourceFile), end);
|
||||
@@ -337,7 +373,7 @@ namespace ts.Completions {
|
||||
if (origin && originIsPromise(origin) && propertyAccessToConvert) {
|
||||
if (insertText === undefined) insertText = name;
|
||||
const awaitText = `(await ${propertyAccessToConvert.expression.getText()})`;
|
||||
insertText = needsConvertPropertyAccess ? `${awaitText}${insertText}` : `${awaitText}.${insertText}`;
|
||||
insertText = needsConvertPropertyAccess ? `${awaitText}${insertText}` : `${awaitText}${insertQuestionDot ? "?." : "."}${insertText}`;
|
||||
replacementSpan = createTextSpanFromBounds(propertyAccessToConvert.getStart(sourceFile), propertyAccessToConvert.end);
|
||||
}
|
||||
|
||||
@@ -846,6 +882,7 @@ namespace ts.Completions {
|
||||
let node = currentToken;
|
||||
let propertyAccessToConvert: PropertyAccessExpression | undefined;
|
||||
let isRightOfDot = false;
|
||||
let isRightOfQuestionDot = false;
|
||||
let isRightOfOpenTag = false;
|
||||
let isStartingCloseTag = false;
|
||||
let isJsxInitializer: IsJsxInitializer = false;
|
||||
@@ -859,8 +896,9 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
let parent = contextToken.parent;
|
||||
if (contextToken.kind === SyntaxKind.DotToken) {
|
||||
isRightOfDot = true;
|
||||
if (contextToken.kind === SyntaxKind.DotToken || contextToken.kind === SyntaxKind.QuestionDotToken) {
|
||||
isRightOfDot = contextToken.kind === SyntaxKind.DotToken;
|
||||
isRightOfQuestionDot = contextToken.kind === SyntaxKind.QuestionDotToken;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
propertyAccessToConvert = parent as PropertyAccessExpression;
|
||||
@@ -967,7 +1005,7 @@ namespace ts.Completions {
|
||||
const symbolToSortTextMap: SymbolSortTextMap = [];
|
||||
const importSuggestionsCache = host.getImportSuggestionsCache && host.getImportSuggestionsCache();
|
||||
|
||||
if (isRightOfDot) {
|
||||
if (isRightOfDot || isRightOfQuestionDot) {
|
||||
getTypeScriptMemberSymbols();
|
||||
}
|
||||
else if (isRightOfOpenTag) {
|
||||
@@ -1074,7 +1112,13 @@ namespace ts.Completions {
|
||||
if (!isTypeLocation &&
|
||||
symbol.declarations &&
|
||||
symbol.declarations.some(d => d.kind !== SyntaxKind.SourceFile && d.kind !== SyntaxKind.ModuleDeclaration && d.kind !== SyntaxKind.EnumDeclaration)) {
|
||||
addTypeProperties(typeChecker.getTypeOfSymbolAtLocation(symbol, node), !!(node.flags & NodeFlags.AwaitContext));
|
||||
let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node).getNonOptionalType();
|
||||
let insertQuestionDot = false;
|
||||
if (type.isNullableType()) {
|
||||
insertQuestionDot = isRightOfDot && !isRightOfQuestionDot;
|
||||
type = type.getNonNullableType();
|
||||
}
|
||||
addTypeProperties(type, !!(node.flags & NodeFlags.AwaitContext), insertQuestionDot);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1089,12 +1133,21 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (!isTypeLocation) {
|
||||
addTypeProperties(typeChecker.getTypeAtLocation(node), !!(node.flags & NodeFlags.AwaitContext));
|
||||
let type = typeChecker.getTypeAtLocation(node).getNonOptionalType();
|
||||
let insertQuestionDot = false;
|
||||
if (type.isNullableType()) {
|
||||
insertQuestionDot = isRightOfDot && !isRightOfQuestionDot;
|
||||
type = type.getNonNullableType();
|
||||
}
|
||||
addTypeProperties(type, !!(node.flags & NodeFlags.AwaitContext), insertQuestionDot);
|
||||
}
|
||||
}
|
||||
|
||||
function addTypeProperties(type: Type, insertAwait?: boolean): void {
|
||||
function addTypeProperties(type: Type, insertAwait: boolean, insertQuestionDot: boolean): void {
|
||||
isNewIdentifierLocation = !!type.getStringIndexType();
|
||||
if (isRightOfQuestionDot && some(type.getCallSignatures())) {
|
||||
isNewIdentifierLocation = true;
|
||||
}
|
||||
|
||||
const propertyAccess = node.kind === SyntaxKind.ImportType ? <ImportTypeNode>node : <PropertyAccessExpression | QualifiedName>node.parent;
|
||||
if (isUncheckedFile) {
|
||||
@@ -1108,7 +1161,7 @@ namespace ts.Completions {
|
||||
else {
|
||||
for (const symbol of type.getApparentProperties()) {
|
||||
if (typeChecker.isValidPropertyAccessForCompletions(propertyAccess, type, symbol)) {
|
||||
addPropertySymbol(symbol);
|
||||
addPropertySymbol(symbol, /*insertAwait*/ false, insertQuestionDot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1118,14 +1171,14 @@ namespace ts.Completions {
|
||||
if (promiseType) {
|
||||
for (const symbol of promiseType.getApparentProperties()) {
|
||||
if (typeChecker.isValidPropertyAccessForCompletions(propertyAccess, promiseType, symbol)) {
|
||||
addPropertySymbol(symbol, /* insertAwait */ true);
|
||||
addPropertySymbol(symbol, /* insertAwait */ true, insertQuestionDot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addPropertySymbol(symbol: Symbol, insertAwait?: boolean) {
|
||||
function addPropertySymbol(symbol: Symbol, insertAwait: boolean, insertQuestionDot: boolean) {
|
||||
// For a computed property with an accessible name like `Symbol.iterator`,
|
||||
// we'll add a completion for the *name* `Symbol` instead of for the property.
|
||||
// If this is e.g. [Symbol.iterator], add a completion for `Symbol`.
|
||||
@@ -1139,23 +1192,34 @@ namespace ts.Completions {
|
||||
symbols.push(firstAccessibleSymbol);
|
||||
const moduleSymbol = firstAccessibleSymbol.parent;
|
||||
symbolToOriginInfoMap[getSymbolId(firstAccessibleSymbol)] =
|
||||
!moduleSymbol || !isExternalModuleSymbol(moduleSymbol) ? { kind: SymbolOriginInfoKind.SymbolMemberNoExport } : { kind: SymbolOriginInfoKind.SymbolMemberExport, moduleSymbol, isDefaultExport: false };
|
||||
!moduleSymbol || !isExternalModuleSymbol(moduleSymbol)
|
||||
? { kind: getNullableSymbolOriginInfoKind(SymbolOriginInfoKind.SymbolMemberNoExport) }
|
||||
: { kind: getNullableSymbolOriginInfoKind(SymbolOriginInfoKind.SymbolMemberExport), moduleSymbol, isDefaultExport: false };
|
||||
}
|
||||
else if (preferences.includeCompletionsWithInsertText) {
|
||||
addPromiseSymbolOriginInfo(symbol);
|
||||
addSymbolOriginInfo(symbol);
|
||||
symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
else {
|
||||
addPromiseSymbolOriginInfo(symbol);
|
||||
addSymbolOriginInfo(symbol);
|
||||
symbols.push(symbol);
|
||||
}
|
||||
|
||||
function addPromiseSymbolOriginInfo (symbol: Symbol) {
|
||||
if (insertAwait && preferences.includeCompletionsWithInsertText && !symbolToOriginInfoMap[getSymbolId(symbol)]) {
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { kind: SymbolOriginInfoKind.Promise };
|
||||
function addSymbolOriginInfo(symbol: Symbol) {
|
||||
if (preferences.includeCompletionsWithInsertText) {
|
||||
if (insertAwait && !symbolToOriginInfoMap[getSymbolId(symbol)]) {
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { kind: getNullableSymbolOriginInfoKind(SymbolOriginInfoKind.Promise) };
|
||||
}
|
||||
else if (insertQuestionDot) {
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { kind: SymbolOriginInfoKind.Nullable };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNullableSymbolOriginInfoKind(kind: SymbolOriginInfoKind) {
|
||||
return insertQuestionDot ? kind | SymbolOriginInfoKind.Nullable : kind;
|
||||
}
|
||||
}
|
||||
|
||||
/** Given 'a.b.c', returns 'a'. */
|
||||
|
||||
@@ -409,9 +409,15 @@ namespace ts {
|
||||
getBaseTypes(): BaseType[] | undefined {
|
||||
return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined;
|
||||
}
|
||||
isNullableType(): boolean {
|
||||
return this.checker.isNullableType(this);
|
||||
}
|
||||
getNonNullableType(): Type {
|
||||
return this.checker.getNonNullableType(this);
|
||||
}
|
||||
getNonOptionalType(): Type {
|
||||
return this.checker.getNonOptionalType(this);
|
||||
}
|
||||
getConstraint(): Type | undefined {
|
||||
return this.checker.getBaseConstraintOfType(this);
|
||||
}
|
||||
|
||||
@@ -1061,6 +1061,8 @@ namespace ts.textChanges {
|
||||
getColumn,
|
||||
getIndent,
|
||||
isAtStartOfLine,
|
||||
hasTrailingComment: () => writer.hasTrailingComment(),
|
||||
hasTrailingWhitespace: () => writer.hasTrailingWhitespace(),
|
||||
clear
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ namespace ts {
|
||||
getNumberIndexType(): Type | undefined;
|
||||
getBaseTypes(): BaseType[] | undefined;
|
||||
getNonNullableType(): Type;
|
||||
/*@internal*/ getNonOptionalType(): Type;
|
||||
/*@internal*/ isNullableType(): boolean;
|
||||
getConstraint(): Type | undefined;
|
||||
getDefault(): Type | undefined;
|
||||
|
||||
|
||||
@@ -956,6 +956,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function removeOptionality(type: Type, isOptionalExpression: boolean, isOptionalChain: boolean) {
|
||||
return isOptionalExpression ? type.getNonNullableType() :
|
||||
isOptionalChain ? type.getNonOptionalType() :
|
||||
type;
|
||||
}
|
||||
|
||||
export function isPossiblyTypeArgumentPosition(token: Node, sourceFile: SourceFile, checker: TypeChecker): boolean {
|
||||
const info = getPossibleTypeArgumentsInfo(token, sourceFile);
|
||||
return info !== undefined && (isPartOfTypeNode(info.called) ||
|
||||
@@ -964,7 +970,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getPossibleGenericSignatures(called: Expression, typeArgumentCount: number, checker: TypeChecker): readonly Signature[] {
|
||||
const type = checker.getTypeAtLocation(called);
|
||||
let type = checker.getTypeAtLocation(called);
|
||||
if (isOptionalChain(called.parent)) {
|
||||
type = removeOptionality(type, !!called.parent.questionDotToken, /*isOptionalChain*/ true);
|
||||
}
|
||||
|
||||
const signatures = isNewExpression(called.parent) ? type.getConstructSignatures() : type.getCallSignatures();
|
||||
return signatures.filter(candidate => !!candidate.typeParameters && candidate.typeParameters.length >= typeArgumentCount);
|
||||
}
|
||||
@@ -993,6 +1003,9 @@ namespace ts {
|
||||
case SyntaxKind.LessThanToken:
|
||||
// Found the beginning of the generic argument expression
|
||||
token = findPrecedingToken(token.getFullStart(), sourceFile);
|
||||
if (token && token.kind === SyntaxKind.QuestionDotToken) {
|
||||
token = findPrecedingToken(token.getFullStart(), sourceFile);
|
||||
}
|
||||
if (!token || !isIdentifier(token)) return undefined;
|
||||
if (!remainingLessThanTokens) {
|
||||
return isDeclarationName(token) ? undefined : { called: token, nTypeArguments };
|
||||
@@ -1493,6 +1506,8 @@ namespace ts {
|
||||
getColumn: () => 0,
|
||||
getLine: () => 0,
|
||||
isAtStartOfLine: () => false,
|
||||
hasTrailingWhitespace: () => false,
|
||||
hasTrailingComment: () => false,
|
||||
rawWrite: notImplemented,
|
||||
getIndent: () => indent,
|
||||
increaseIndent: () => { indent++; },
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
"unittests/evaluation/awaiter.ts",
|
||||
"unittests/evaluation/forAwaitOf.ts",
|
||||
"unittests/evaluation/forOf.ts",
|
||||
"unittests/evaluation/optionalCall.ts",
|
||||
"unittests/evaluation/objectRest.ts",
|
||||
"unittests/services/cancellableLanguageServiceOperations.ts",
|
||||
"unittests/services/colorization.ts",
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
describe("unittests:: evaluation:: optionalCall", () => {
|
||||
it("f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
function f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
export const output: any[] = [];
|
||||
f?.(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.isUndefined(result.output[1]);
|
||||
});
|
||||
it("o.f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o.f?.(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o);
|
||||
});
|
||||
it("o.x.f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
x: {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o.x.f?.(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o.x);
|
||||
});
|
||||
it("o?.f()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o?.f(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o);
|
||||
});
|
||||
it("o?.f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o?.f?.(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o);
|
||||
});
|
||||
it("o.x?.f()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
x: {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o.x?.f(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o.x);
|
||||
});
|
||||
it("o?.x.f()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
x: {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o?.x.f(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o.x);
|
||||
});
|
||||
it("o?.x?.f()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
x: {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o?.x?.f(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o.x);
|
||||
});
|
||||
it("o?.x?.f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
x: {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
export const output: any[] = [];
|
||||
o?.x?.f?.(1);
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], result.o.x);
|
||||
});
|
||||
it("f?.()?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
function g(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
function f(a) {
|
||||
output.push(a);
|
||||
return g;
|
||||
}
|
||||
export const output: any[] = [];
|
||||
f?.(1)?.(2)
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], 2);
|
||||
assert.isUndefined(result.output[2]);
|
||||
});
|
||||
it("f?.().f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
};
|
||||
function f(a) {
|
||||
output.push(a);
|
||||
return o;
|
||||
}
|
||||
export const output: any[] = [];
|
||||
f?.(1).f?.(2)
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], 2);
|
||||
assert.strictEqual(result.output[2], result.o);
|
||||
});
|
||||
it("f?.()?.f?.()", async () => {
|
||||
const result = evaluator.evaluateTypeScript(`
|
||||
export const o = {
|
||||
f(a) {
|
||||
output.push(a);
|
||||
output.push(this);
|
||||
}
|
||||
};
|
||||
function f(a) {
|
||||
output.push(a);
|
||||
return o;
|
||||
}
|
||||
export const output: any[] = [];
|
||||
f?.(1)?.f?.(2)
|
||||
`);
|
||||
assert.strictEqual(result.output[0], 1);
|
||||
assert.strictEqual(result.output[1], 2);
|
||||
assert.strictEqual(result.output[2], result.o);
|
||||
});
|
||||
});
|
||||
+365
-337
@@ -104,332 +104,334 @@ declare namespace ts {
|
||||
DotDotDotToken = 25,
|
||||
SemicolonToken = 26,
|
||||
CommaToken = 27,
|
||||
LessThanToken = 28,
|
||||
LessThanSlashToken = 29,
|
||||
GreaterThanToken = 30,
|
||||
LessThanEqualsToken = 31,
|
||||
GreaterThanEqualsToken = 32,
|
||||
EqualsEqualsToken = 33,
|
||||
ExclamationEqualsToken = 34,
|
||||
EqualsEqualsEqualsToken = 35,
|
||||
ExclamationEqualsEqualsToken = 36,
|
||||
EqualsGreaterThanToken = 37,
|
||||
PlusToken = 38,
|
||||
MinusToken = 39,
|
||||
AsteriskToken = 40,
|
||||
AsteriskAsteriskToken = 41,
|
||||
SlashToken = 42,
|
||||
PercentToken = 43,
|
||||
PlusPlusToken = 44,
|
||||
MinusMinusToken = 45,
|
||||
LessThanLessThanToken = 46,
|
||||
GreaterThanGreaterThanToken = 47,
|
||||
GreaterThanGreaterThanGreaterThanToken = 48,
|
||||
AmpersandToken = 49,
|
||||
BarToken = 50,
|
||||
CaretToken = 51,
|
||||
ExclamationToken = 52,
|
||||
TildeToken = 53,
|
||||
AmpersandAmpersandToken = 54,
|
||||
BarBarToken = 55,
|
||||
QuestionToken = 56,
|
||||
ColonToken = 57,
|
||||
AtToken = 58,
|
||||
QuestionDotToken = 28,
|
||||
LessThanToken = 29,
|
||||
LessThanSlashToken = 30,
|
||||
GreaterThanToken = 31,
|
||||
LessThanEqualsToken = 32,
|
||||
GreaterThanEqualsToken = 33,
|
||||
EqualsEqualsToken = 34,
|
||||
ExclamationEqualsToken = 35,
|
||||
EqualsEqualsEqualsToken = 36,
|
||||
ExclamationEqualsEqualsToken = 37,
|
||||
EqualsGreaterThanToken = 38,
|
||||
PlusToken = 39,
|
||||
MinusToken = 40,
|
||||
AsteriskToken = 41,
|
||||
AsteriskAsteriskToken = 42,
|
||||
SlashToken = 43,
|
||||
PercentToken = 44,
|
||||
PlusPlusToken = 45,
|
||||
MinusMinusToken = 46,
|
||||
LessThanLessThanToken = 47,
|
||||
GreaterThanGreaterThanToken = 48,
|
||||
GreaterThanGreaterThanGreaterThanToken = 49,
|
||||
AmpersandToken = 50,
|
||||
BarToken = 51,
|
||||
CaretToken = 52,
|
||||
ExclamationToken = 53,
|
||||
TildeToken = 54,
|
||||
AmpersandAmpersandToken = 55,
|
||||
BarBarToken = 56,
|
||||
QuestionToken = 57,
|
||||
ColonToken = 58,
|
||||
AtToken = 59,
|
||||
/** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */
|
||||
BacktickToken = 59,
|
||||
EqualsToken = 60,
|
||||
PlusEqualsToken = 61,
|
||||
MinusEqualsToken = 62,
|
||||
AsteriskEqualsToken = 63,
|
||||
AsteriskAsteriskEqualsToken = 64,
|
||||
SlashEqualsToken = 65,
|
||||
PercentEqualsToken = 66,
|
||||
LessThanLessThanEqualsToken = 67,
|
||||
GreaterThanGreaterThanEqualsToken = 68,
|
||||
GreaterThanGreaterThanGreaterThanEqualsToken = 69,
|
||||
AmpersandEqualsToken = 70,
|
||||
BarEqualsToken = 71,
|
||||
CaretEqualsToken = 72,
|
||||
Identifier = 73,
|
||||
BreakKeyword = 74,
|
||||
CaseKeyword = 75,
|
||||
CatchKeyword = 76,
|
||||
ClassKeyword = 77,
|
||||
ConstKeyword = 78,
|
||||
ContinueKeyword = 79,
|
||||
DebuggerKeyword = 80,
|
||||
DefaultKeyword = 81,
|
||||
DeleteKeyword = 82,
|
||||
DoKeyword = 83,
|
||||
ElseKeyword = 84,
|
||||
EnumKeyword = 85,
|
||||
ExportKeyword = 86,
|
||||
ExtendsKeyword = 87,
|
||||
FalseKeyword = 88,
|
||||
FinallyKeyword = 89,
|
||||
ForKeyword = 90,
|
||||
FunctionKeyword = 91,
|
||||
IfKeyword = 92,
|
||||
ImportKeyword = 93,
|
||||
InKeyword = 94,
|
||||
InstanceOfKeyword = 95,
|
||||
NewKeyword = 96,
|
||||
NullKeyword = 97,
|
||||
ReturnKeyword = 98,
|
||||
SuperKeyword = 99,
|
||||
SwitchKeyword = 100,
|
||||
ThisKeyword = 101,
|
||||
ThrowKeyword = 102,
|
||||
TrueKeyword = 103,
|
||||
TryKeyword = 104,
|
||||
TypeOfKeyword = 105,
|
||||
VarKeyword = 106,
|
||||
VoidKeyword = 107,
|
||||
WhileKeyword = 108,
|
||||
WithKeyword = 109,
|
||||
ImplementsKeyword = 110,
|
||||
InterfaceKeyword = 111,
|
||||
LetKeyword = 112,
|
||||
PackageKeyword = 113,
|
||||
PrivateKeyword = 114,
|
||||
ProtectedKeyword = 115,
|
||||
PublicKeyword = 116,
|
||||
StaticKeyword = 117,
|
||||
YieldKeyword = 118,
|
||||
AbstractKeyword = 119,
|
||||
AsKeyword = 120,
|
||||
AssertsKeyword = 121,
|
||||
AnyKeyword = 122,
|
||||
AsyncKeyword = 123,
|
||||
AwaitKeyword = 124,
|
||||
BooleanKeyword = 125,
|
||||
ConstructorKeyword = 126,
|
||||
DeclareKeyword = 127,
|
||||
GetKeyword = 128,
|
||||
InferKeyword = 129,
|
||||
IsKeyword = 130,
|
||||
KeyOfKeyword = 131,
|
||||
ModuleKeyword = 132,
|
||||
NamespaceKeyword = 133,
|
||||
NeverKeyword = 134,
|
||||
ReadonlyKeyword = 135,
|
||||
RequireKeyword = 136,
|
||||
NumberKeyword = 137,
|
||||
ObjectKeyword = 138,
|
||||
SetKeyword = 139,
|
||||
StringKeyword = 140,
|
||||
SymbolKeyword = 141,
|
||||
TypeKeyword = 142,
|
||||
UndefinedKeyword = 143,
|
||||
UniqueKeyword = 144,
|
||||
UnknownKeyword = 145,
|
||||
FromKeyword = 146,
|
||||
GlobalKeyword = 147,
|
||||
BigIntKeyword = 148,
|
||||
OfKeyword = 149,
|
||||
QualifiedName = 150,
|
||||
ComputedPropertyName = 151,
|
||||
TypeParameter = 152,
|
||||
Parameter = 153,
|
||||
Decorator = 154,
|
||||
PropertySignature = 155,
|
||||
PropertyDeclaration = 156,
|
||||
MethodSignature = 157,
|
||||
MethodDeclaration = 158,
|
||||
Constructor = 159,
|
||||
GetAccessor = 160,
|
||||
SetAccessor = 161,
|
||||
CallSignature = 162,
|
||||
ConstructSignature = 163,
|
||||
IndexSignature = 164,
|
||||
TypePredicate = 165,
|
||||
TypeReference = 166,
|
||||
FunctionType = 167,
|
||||
ConstructorType = 168,
|
||||
TypeQuery = 169,
|
||||
TypeLiteral = 170,
|
||||
ArrayType = 171,
|
||||
TupleType = 172,
|
||||
OptionalType = 173,
|
||||
RestType = 174,
|
||||
UnionType = 175,
|
||||
IntersectionType = 176,
|
||||
ConditionalType = 177,
|
||||
InferType = 178,
|
||||
ParenthesizedType = 179,
|
||||
ThisType = 180,
|
||||
TypeOperator = 181,
|
||||
IndexedAccessType = 182,
|
||||
MappedType = 183,
|
||||
LiteralType = 184,
|
||||
ImportType = 185,
|
||||
ObjectBindingPattern = 186,
|
||||
ArrayBindingPattern = 187,
|
||||
BindingElement = 188,
|
||||
ArrayLiteralExpression = 189,
|
||||
ObjectLiteralExpression = 190,
|
||||
PropertyAccessExpression = 191,
|
||||
ElementAccessExpression = 192,
|
||||
CallExpression = 193,
|
||||
NewExpression = 194,
|
||||
TaggedTemplateExpression = 195,
|
||||
TypeAssertionExpression = 196,
|
||||
ParenthesizedExpression = 197,
|
||||
FunctionExpression = 198,
|
||||
ArrowFunction = 199,
|
||||
DeleteExpression = 200,
|
||||
TypeOfExpression = 201,
|
||||
VoidExpression = 202,
|
||||
AwaitExpression = 203,
|
||||
PrefixUnaryExpression = 204,
|
||||
PostfixUnaryExpression = 205,
|
||||
BinaryExpression = 206,
|
||||
ConditionalExpression = 207,
|
||||
TemplateExpression = 208,
|
||||
YieldExpression = 209,
|
||||
SpreadElement = 210,
|
||||
ClassExpression = 211,
|
||||
OmittedExpression = 212,
|
||||
ExpressionWithTypeArguments = 213,
|
||||
AsExpression = 214,
|
||||
NonNullExpression = 215,
|
||||
MetaProperty = 216,
|
||||
SyntheticExpression = 217,
|
||||
TemplateSpan = 218,
|
||||
SemicolonClassElement = 219,
|
||||
Block = 220,
|
||||
EmptyStatement = 221,
|
||||
VariableStatement = 222,
|
||||
ExpressionStatement = 223,
|
||||
IfStatement = 224,
|
||||
DoStatement = 225,
|
||||
WhileStatement = 226,
|
||||
ForStatement = 227,
|
||||
ForInStatement = 228,
|
||||
ForOfStatement = 229,
|
||||
ContinueStatement = 230,
|
||||
BreakStatement = 231,
|
||||
ReturnStatement = 232,
|
||||
WithStatement = 233,
|
||||
SwitchStatement = 234,
|
||||
LabeledStatement = 235,
|
||||
ThrowStatement = 236,
|
||||
TryStatement = 237,
|
||||
DebuggerStatement = 238,
|
||||
VariableDeclaration = 239,
|
||||
VariableDeclarationList = 240,
|
||||
FunctionDeclaration = 241,
|
||||
ClassDeclaration = 242,
|
||||
InterfaceDeclaration = 243,
|
||||
TypeAliasDeclaration = 244,
|
||||
EnumDeclaration = 245,
|
||||
ModuleDeclaration = 246,
|
||||
ModuleBlock = 247,
|
||||
CaseBlock = 248,
|
||||
NamespaceExportDeclaration = 249,
|
||||
ImportEqualsDeclaration = 250,
|
||||
ImportDeclaration = 251,
|
||||
ImportClause = 252,
|
||||
NamespaceImport = 253,
|
||||
NamedImports = 254,
|
||||
ImportSpecifier = 255,
|
||||
ExportAssignment = 256,
|
||||
ExportDeclaration = 257,
|
||||
NamedExports = 258,
|
||||
ExportSpecifier = 259,
|
||||
MissingDeclaration = 260,
|
||||
ExternalModuleReference = 261,
|
||||
JsxElement = 262,
|
||||
JsxSelfClosingElement = 263,
|
||||
JsxOpeningElement = 264,
|
||||
JsxClosingElement = 265,
|
||||
JsxFragment = 266,
|
||||
JsxOpeningFragment = 267,
|
||||
JsxClosingFragment = 268,
|
||||
JsxAttribute = 269,
|
||||
JsxAttributes = 270,
|
||||
JsxSpreadAttribute = 271,
|
||||
JsxExpression = 272,
|
||||
CaseClause = 273,
|
||||
DefaultClause = 274,
|
||||
HeritageClause = 275,
|
||||
CatchClause = 276,
|
||||
PropertyAssignment = 277,
|
||||
ShorthandPropertyAssignment = 278,
|
||||
SpreadAssignment = 279,
|
||||
EnumMember = 280,
|
||||
UnparsedPrologue = 281,
|
||||
UnparsedPrepend = 282,
|
||||
UnparsedText = 283,
|
||||
UnparsedInternalText = 284,
|
||||
UnparsedSyntheticReference = 285,
|
||||
SourceFile = 286,
|
||||
Bundle = 287,
|
||||
UnparsedSource = 288,
|
||||
InputFiles = 289,
|
||||
JSDocTypeExpression = 290,
|
||||
JSDocAllType = 291,
|
||||
JSDocUnknownType = 292,
|
||||
JSDocNullableType = 293,
|
||||
JSDocNonNullableType = 294,
|
||||
JSDocOptionalType = 295,
|
||||
JSDocFunctionType = 296,
|
||||
JSDocVariadicType = 297,
|
||||
JSDocNamepathType = 298,
|
||||
JSDocComment = 299,
|
||||
JSDocTypeLiteral = 300,
|
||||
JSDocSignature = 301,
|
||||
JSDocTag = 302,
|
||||
JSDocAugmentsTag = 303,
|
||||
JSDocAuthorTag = 304,
|
||||
JSDocClassTag = 305,
|
||||
JSDocCallbackTag = 306,
|
||||
JSDocEnumTag = 307,
|
||||
JSDocParameterTag = 308,
|
||||
JSDocReturnTag = 309,
|
||||
JSDocThisTag = 310,
|
||||
JSDocTypeTag = 311,
|
||||
JSDocTemplateTag = 312,
|
||||
JSDocTypedefTag = 313,
|
||||
JSDocPropertyTag = 314,
|
||||
SyntaxList = 315,
|
||||
NotEmittedStatement = 316,
|
||||
PartiallyEmittedExpression = 317,
|
||||
CommaListExpression = 318,
|
||||
MergeDeclarationMarker = 319,
|
||||
EndOfDeclarationMarker = 320,
|
||||
Count = 321,
|
||||
FirstAssignment = 60,
|
||||
LastAssignment = 72,
|
||||
FirstCompoundAssignment = 61,
|
||||
LastCompoundAssignment = 72,
|
||||
FirstReservedWord = 74,
|
||||
LastReservedWord = 109,
|
||||
FirstKeyword = 74,
|
||||
LastKeyword = 149,
|
||||
FirstFutureReservedWord = 110,
|
||||
LastFutureReservedWord = 118,
|
||||
FirstTypeNode = 165,
|
||||
LastTypeNode = 185,
|
||||
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,
|
||||
FirstPunctuation = 18,
|
||||
LastPunctuation = 72,
|
||||
LastPunctuation = 73,
|
||||
FirstToken = 0,
|
||||
LastToken = 149,
|
||||
LastToken = 150,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
LastLiteralToken = 14,
|
||||
FirstTemplateToken = 14,
|
||||
LastTemplateToken = 17,
|
||||
FirstBinaryOperator = 28,
|
||||
LastBinaryOperator = 72,
|
||||
FirstStatement = 222,
|
||||
LastStatement = 238,
|
||||
FirstNode = 150,
|
||||
FirstJSDocNode = 290,
|
||||
LastJSDocNode = 314,
|
||||
FirstJSDocTagNode = 302,
|
||||
LastJSDocTagNode = 314,
|
||||
FirstBinaryOperator = 29,
|
||||
LastBinaryOperator = 73,
|
||||
FirstStatement = 223,
|
||||
LastStatement = 239,
|
||||
FirstNode = 151,
|
||||
FirstJSDocNode = 291,
|
||||
LastJSDocNode = 315,
|
||||
FirstJSDocTagNode = 303,
|
||||
LastJSDocTagNode = 315,
|
||||
}
|
||||
export enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -438,27 +440,28 @@ declare namespace ts {
|
||||
NestedNamespace = 4,
|
||||
Synthesized = 8,
|
||||
Namespace = 16,
|
||||
ExportContext = 32,
|
||||
ContainsThis = 64,
|
||||
HasImplicitReturn = 128,
|
||||
HasExplicitReturn = 256,
|
||||
GlobalAugmentation = 512,
|
||||
HasAsyncFunctions = 1024,
|
||||
DisallowInContext = 2048,
|
||||
YieldContext = 4096,
|
||||
DecoratorContext = 8192,
|
||||
AwaitContext = 16384,
|
||||
ThisNodeHasError = 32768,
|
||||
JavaScriptFile = 65536,
|
||||
ThisNodeOrAnySubNodesHasError = 131072,
|
||||
HasAggregatedChildData = 262144,
|
||||
JSDoc = 2097152,
|
||||
JsonFile = 16777216,
|
||||
OptionalChain = 32,
|
||||
ExportContext = 64,
|
||||
ContainsThis = 128,
|
||||
HasImplicitReturn = 256,
|
||||
HasExplicitReturn = 512,
|
||||
GlobalAugmentation = 1024,
|
||||
HasAsyncFunctions = 2048,
|
||||
DisallowInContext = 4096,
|
||||
YieldContext = 8192,
|
||||
DecoratorContext = 16384,
|
||||
AwaitContext = 32768,
|
||||
ThisNodeHasError = 65536,
|
||||
JavaScriptFile = 131072,
|
||||
ThisNodeOrAnySubNodesHasError = 262144,
|
||||
HasAggregatedChildData = 524288,
|
||||
JSDoc = 4194304,
|
||||
JsonFile = 33554432,
|
||||
BlockScoped = 3,
|
||||
ReachabilityCheckFlags = 384,
|
||||
ReachabilityAndEmitFlags = 1408,
|
||||
ContextFlags = 12679168,
|
||||
TypeExcludesFlags = 20480,
|
||||
ReachabilityCheckFlags = 768,
|
||||
ReachabilityAndEmitFlags = 2816,
|
||||
ContextFlags = 25358336,
|
||||
TypeExcludesFlags = 40960,
|
||||
}
|
||||
export enum ModifierFlags {
|
||||
None = 0,
|
||||
@@ -508,8 +511,10 @@ declare namespace ts {
|
||||
export interface Token<TKind extends SyntaxKind> extends Node {
|
||||
kind: TKind;
|
||||
}
|
||||
export type DotToken = Token<SyntaxKind.DotToken>;
|
||||
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
export type QuestionDotToken = Token<SyntaxKind.QuestionDotToken>;
|
||||
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
export type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
@@ -1082,8 +1087,12 @@ declare namespace ts {
|
||||
export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration {
|
||||
kind: SyntaxKind.PropertyAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
name: Identifier;
|
||||
}
|
||||
export interface PropertyAccessChain extends PropertyAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -1095,8 +1104,12 @@ declare namespace ts {
|
||||
export interface ElementAccessExpression extends MemberExpression {
|
||||
kind: SyntaxKind.ElementAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
argumentExpression: Expression;
|
||||
}
|
||||
export interface ElementAccessChain extends ElementAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
export interface SuperElementAccessExpression extends ElementAccessExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -1104,9 +1117,14 @@ declare namespace ts {
|
||||
export interface CallExpression extends LeftHandSideExpression, Declaration {
|
||||
kind: SyntaxKind.CallExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
arguments: NodeArray<Expression>;
|
||||
}
|
||||
export interface CallChain extends CallExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
export type OptionalChain = PropertyAccessChain | ElementAccessChain | CallChain;
|
||||
export interface SuperCall extends CallExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -3496,8 +3514,12 @@ declare namespace ts {
|
||||
function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression;
|
||||
function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression;
|
||||
function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression;
|
||||
function isPropertyAccessChain(node: Node): node is PropertyAccessChain;
|
||||
function isElementAccessExpression(node: Node): node is ElementAccessExpression;
|
||||
function isElementAccessChain(node: Node): node is ElementAccessChain;
|
||||
function isCallExpression(node: Node): node is CallExpression;
|
||||
function isCallChain(node: Node): node is CallChain;
|
||||
function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain;
|
||||
function isNewExpression(node: Node): node is NewExpression;
|
||||
function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression;
|
||||
function isTypeAssertion(node: Node): node is TypeAssertion;
|
||||
@@ -3943,10 +3965,16 @@ declare namespace ts {
|
||||
function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression;
|
||||
function createPropertyAccess(expression: Expression, name: string | Identifier): PropertyAccessExpression;
|
||||
function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression;
|
||||
function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain;
|
||||
function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain;
|
||||
function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain;
|
||||
function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain;
|
||||
function createCall(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression;
|
||||
function updateCall(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression;
|
||||
function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain;
|
||||
function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain;
|
||||
function createNew(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression;
|
||||
function updateNew(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression;
|
||||
/** @deprecated */ function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
|
||||
+365
-337
@@ -104,332 +104,334 @@ declare namespace ts {
|
||||
DotDotDotToken = 25,
|
||||
SemicolonToken = 26,
|
||||
CommaToken = 27,
|
||||
LessThanToken = 28,
|
||||
LessThanSlashToken = 29,
|
||||
GreaterThanToken = 30,
|
||||
LessThanEqualsToken = 31,
|
||||
GreaterThanEqualsToken = 32,
|
||||
EqualsEqualsToken = 33,
|
||||
ExclamationEqualsToken = 34,
|
||||
EqualsEqualsEqualsToken = 35,
|
||||
ExclamationEqualsEqualsToken = 36,
|
||||
EqualsGreaterThanToken = 37,
|
||||
PlusToken = 38,
|
||||
MinusToken = 39,
|
||||
AsteriskToken = 40,
|
||||
AsteriskAsteriskToken = 41,
|
||||
SlashToken = 42,
|
||||
PercentToken = 43,
|
||||
PlusPlusToken = 44,
|
||||
MinusMinusToken = 45,
|
||||
LessThanLessThanToken = 46,
|
||||
GreaterThanGreaterThanToken = 47,
|
||||
GreaterThanGreaterThanGreaterThanToken = 48,
|
||||
AmpersandToken = 49,
|
||||
BarToken = 50,
|
||||
CaretToken = 51,
|
||||
ExclamationToken = 52,
|
||||
TildeToken = 53,
|
||||
AmpersandAmpersandToken = 54,
|
||||
BarBarToken = 55,
|
||||
QuestionToken = 56,
|
||||
ColonToken = 57,
|
||||
AtToken = 58,
|
||||
QuestionDotToken = 28,
|
||||
LessThanToken = 29,
|
||||
LessThanSlashToken = 30,
|
||||
GreaterThanToken = 31,
|
||||
LessThanEqualsToken = 32,
|
||||
GreaterThanEqualsToken = 33,
|
||||
EqualsEqualsToken = 34,
|
||||
ExclamationEqualsToken = 35,
|
||||
EqualsEqualsEqualsToken = 36,
|
||||
ExclamationEqualsEqualsToken = 37,
|
||||
EqualsGreaterThanToken = 38,
|
||||
PlusToken = 39,
|
||||
MinusToken = 40,
|
||||
AsteriskToken = 41,
|
||||
AsteriskAsteriskToken = 42,
|
||||
SlashToken = 43,
|
||||
PercentToken = 44,
|
||||
PlusPlusToken = 45,
|
||||
MinusMinusToken = 46,
|
||||
LessThanLessThanToken = 47,
|
||||
GreaterThanGreaterThanToken = 48,
|
||||
GreaterThanGreaterThanGreaterThanToken = 49,
|
||||
AmpersandToken = 50,
|
||||
BarToken = 51,
|
||||
CaretToken = 52,
|
||||
ExclamationToken = 53,
|
||||
TildeToken = 54,
|
||||
AmpersandAmpersandToken = 55,
|
||||
BarBarToken = 56,
|
||||
QuestionToken = 57,
|
||||
ColonToken = 58,
|
||||
AtToken = 59,
|
||||
/** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */
|
||||
BacktickToken = 59,
|
||||
EqualsToken = 60,
|
||||
PlusEqualsToken = 61,
|
||||
MinusEqualsToken = 62,
|
||||
AsteriskEqualsToken = 63,
|
||||
AsteriskAsteriskEqualsToken = 64,
|
||||
SlashEqualsToken = 65,
|
||||
PercentEqualsToken = 66,
|
||||
LessThanLessThanEqualsToken = 67,
|
||||
GreaterThanGreaterThanEqualsToken = 68,
|
||||
GreaterThanGreaterThanGreaterThanEqualsToken = 69,
|
||||
AmpersandEqualsToken = 70,
|
||||
BarEqualsToken = 71,
|
||||
CaretEqualsToken = 72,
|
||||
Identifier = 73,
|
||||
BreakKeyword = 74,
|
||||
CaseKeyword = 75,
|
||||
CatchKeyword = 76,
|
||||
ClassKeyword = 77,
|
||||
ConstKeyword = 78,
|
||||
ContinueKeyword = 79,
|
||||
DebuggerKeyword = 80,
|
||||
DefaultKeyword = 81,
|
||||
DeleteKeyword = 82,
|
||||
DoKeyword = 83,
|
||||
ElseKeyword = 84,
|
||||
EnumKeyword = 85,
|
||||
ExportKeyword = 86,
|
||||
ExtendsKeyword = 87,
|
||||
FalseKeyword = 88,
|
||||
FinallyKeyword = 89,
|
||||
ForKeyword = 90,
|
||||
FunctionKeyword = 91,
|
||||
IfKeyword = 92,
|
||||
ImportKeyword = 93,
|
||||
InKeyword = 94,
|
||||
InstanceOfKeyword = 95,
|
||||
NewKeyword = 96,
|
||||
NullKeyword = 97,
|
||||
ReturnKeyword = 98,
|
||||
SuperKeyword = 99,
|
||||
SwitchKeyword = 100,
|
||||
ThisKeyword = 101,
|
||||
ThrowKeyword = 102,
|
||||
TrueKeyword = 103,
|
||||
TryKeyword = 104,
|
||||
TypeOfKeyword = 105,
|
||||
VarKeyword = 106,
|
||||
VoidKeyword = 107,
|
||||
WhileKeyword = 108,
|
||||
WithKeyword = 109,
|
||||
ImplementsKeyword = 110,
|
||||
InterfaceKeyword = 111,
|
||||
LetKeyword = 112,
|
||||
PackageKeyword = 113,
|
||||
PrivateKeyword = 114,
|
||||
ProtectedKeyword = 115,
|
||||
PublicKeyword = 116,
|
||||
StaticKeyword = 117,
|
||||
YieldKeyword = 118,
|
||||
AbstractKeyword = 119,
|
||||
AsKeyword = 120,
|
||||
AssertsKeyword = 121,
|
||||
AnyKeyword = 122,
|
||||
AsyncKeyword = 123,
|
||||
AwaitKeyword = 124,
|
||||
BooleanKeyword = 125,
|
||||
ConstructorKeyword = 126,
|
||||
DeclareKeyword = 127,
|
||||
GetKeyword = 128,
|
||||
InferKeyword = 129,
|
||||
IsKeyword = 130,
|
||||
KeyOfKeyword = 131,
|
||||
ModuleKeyword = 132,
|
||||
NamespaceKeyword = 133,
|
||||
NeverKeyword = 134,
|
||||
ReadonlyKeyword = 135,
|
||||
RequireKeyword = 136,
|
||||
NumberKeyword = 137,
|
||||
ObjectKeyword = 138,
|
||||
SetKeyword = 139,
|
||||
StringKeyword = 140,
|
||||
SymbolKeyword = 141,
|
||||
TypeKeyword = 142,
|
||||
UndefinedKeyword = 143,
|
||||
UniqueKeyword = 144,
|
||||
UnknownKeyword = 145,
|
||||
FromKeyword = 146,
|
||||
GlobalKeyword = 147,
|
||||
BigIntKeyword = 148,
|
||||
OfKeyword = 149,
|
||||
QualifiedName = 150,
|
||||
ComputedPropertyName = 151,
|
||||
TypeParameter = 152,
|
||||
Parameter = 153,
|
||||
Decorator = 154,
|
||||
PropertySignature = 155,
|
||||
PropertyDeclaration = 156,
|
||||
MethodSignature = 157,
|
||||
MethodDeclaration = 158,
|
||||
Constructor = 159,
|
||||
GetAccessor = 160,
|
||||
SetAccessor = 161,
|
||||
CallSignature = 162,
|
||||
ConstructSignature = 163,
|
||||
IndexSignature = 164,
|
||||
TypePredicate = 165,
|
||||
TypeReference = 166,
|
||||
FunctionType = 167,
|
||||
ConstructorType = 168,
|
||||
TypeQuery = 169,
|
||||
TypeLiteral = 170,
|
||||
ArrayType = 171,
|
||||
TupleType = 172,
|
||||
OptionalType = 173,
|
||||
RestType = 174,
|
||||
UnionType = 175,
|
||||
IntersectionType = 176,
|
||||
ConditionalType = 177,
|
||||
InferType = 178,
|
||||
ParenthesizedType = 179,
|
||||
ThisType = 180,
|
||||
TypeOperator = 181,
|
||||
IndexedAccessType = 182,
|
||||
MappedType = 183,
|
||||
LiteralType = 184,
|
||||
ImportType = 185,
|
||||
ObjectBindingPattern = 186,
|
||||
ArrayBindingPattern = 187,
|
||||
BindingElement = 188,
|
||||
ArrayLiteralExpression = 189,
|
||||
ObjectLiteralExpression = 190,
|
||||
PropertyAccessExpression = 191,
|
||||
ElementAccessExpression = 192,
|
||||
CallExpression = 193,
|
||||
NewExpression = 194,
|
||||
TaggedTemplateExpression = 195,
|
||||
TypeAssertionExpression = 196,
|
||||
ParenthesizedExpression = 197,
|
||||
FunctionExpression = 198,
|
||||
ArrowFunction = 199,
|
||||
DeleteExpression = 200,
|
||||
TypeOfExpression = 201,
|
||||
VoidExpression = 202,
|
||||
AwaitExpression = 203,
|
||||
PrefixUnaryExpression = 204,
|
||||
PostfixUnaryExpression = 205,
|
||||
BinaryExpression = 206,
|
||||
ConditionalExpression = 207,
|
||||
TemplateExpression = 208,
|
||||
YieldExpression = 209,
|
||||
SpreadElement = 210,
|
||||
ClassExpression = 211,
|
||||
OmittedExpression = 212,
|
||||
ExpressionWithTypeArguments = 213,
|
||||
AsExpression = 214,
|
||||
NonNullExpression = 215,
|
||||
MetaProperty = 216,
|
||||
SyntheticExpression = 217,
|
||||
TemplateSpan = 218,
|
||||
SemicolonClassElement = 219,
|
||||
Block = 220,
|
||||
EmptyStatement = 221,
|
||||
VariableStatement = 222,
|
||||
ExpressionStatement = 223,
|
||||
IfStatement = 224,
|
||||
DoStatement = 225,
|
||||
WhileStatement = 226,
|
||||
ForStatement = 227,
|
||||
ForInStatement = 228,
|
||||
ForOfStatement = 229,
|
||||
ContinueStatement = 230,
|
||||
BreakStatement = 231,
|
||||
ReturnStatement = 232,
|
||||
WithStatement = 233,
|
||||
SwitchStatement = 234,
|
||||
LabeledStatement = 235,
|
||||
ThrowStatement = 236,
|
||||
TryStatement = 237,
|
||||
DebuggerStatement = 238,
|
||||
VariableDeclaration = 239,
|
||||
VariableDeclarationList = 240,
|
||||
FunctionDeclaration = 241,
|
||||
ClassDeclaration = 242,
|
||||
InterfaceDeclaration = 243,
|
||||
TypeAliasDeclaration = 244,
|
||||
EnumDeclaration = 245,
|
||||
ModuleDeclaration = 246,
|
||||
ModuleBlock = 247,
|
||||
CaseBlock = 248,
|
||||
NamespaceExportDeclaration = 249,
|
||||
ImportEqualsDeclaration = 250,
|
||||
ImportDeclaration = 251,
|
||||
ImportClause = 252,
|
||||
NamespaceImport = 253,
|
||||
NamedImports = 254,
|
||||
ImportSpecifier = 255,
|
||||
ExportAssignment = 256,
|
||||
ExportDeclaration = 257,
|
||||
NamedExports = 258,
|
||||
ExportSpecifier = 259,
|
||||
MissingDeclaration = 260,
|
||||
ExternalModuleReference = 261,
|
||||
JsxElement = 262,
|
||||
JsxSelfClosingElement = 263,
|
||||
JsxOpeningElement = 264,
|
||||
JsxClosingElement = 265,
|
||||
JsxFragment = 266,
|
||||
JsxOpeningFragment = 267,
|
||||
JsxClosingFragment = 268,
|
||||
JsxAttribute = 269,
|
||||
JsxAttributes = 270,
|
||||
JsxSpreadAttribute = 271,
|
||||
JsxExpression = 272,
|
||||
CaseClause = 273,
|
||||
DefaultClause = 274,
|
||||
HeritageClause = 275,
|
||||
CatchClause = 276,
|
||||
PropertyAssignment = 277,
|
||||
ShorthandPropertyAssignment = 278,
|
||||
SpreadAssignment = 279,
|
||||
EnumMember = 280,
|
||||
UnparsedPrologue = 281,
|
||||
UnparsedPrepend = 282,
|
||||
UnparsedText = 283,
|
||||
UnparsedInternalText = 284,
|
||||
UnparsedSyntheticReference = 285,
|
||||
SourceFile = 286,
|
||||
Bundle = 287,
|
||||
UnparsedSource = 288,
|
||||
InputFiles = 289,
|
||||
JSDocTypeExpression = 290,
|
||||
JSDocAllType = 291,
|
||||
JSDocUnknownType = 292,
|
||||
JSDocNullableType = 293,
|
||||
JSDocNonNullableType = 294,
|
||||
JSDocOptionalType = 295,
|
||||
JSDocFunctionType = 296,
|
||||
JSDocVariadicType = 297,
|
||||
JSDocNamepathType = 298,
|
||||
JSDocComment = 299,
|
||||
JSDocTypeLiteral = 300,
|
||||
JSDocSignature = 301,
|
||||
JSDocTag = 302,
|
||||
JSDocAugmentsTag = 303,
|
||||
JSDocAuthorTag = 304,
|
||||
JSDocClassTag = 305,
|
||||
JSDocCallbackTag = 306,
|
||||
JSDocEnumTag = 307,
|
||||
JSDocParameterTag = 308,
|
||||
JSDocReturnTag = 309,
|
||||
JSDocThisTag = 310,
|
||||
JSDocTypeTag = 311,
|
||||
JSDocTemplateTag = 312,
|
||||
JSDocTypedefTag = 313,
|
||||
JSDocPropertyTag = 314,
|
||||
SyntaxList = 315,
|
||||
NotEmittedStatement = 316,
|
||||
PartiallyEmittedExpression = 317,
|
||||
CommaListExpression = 318,
|
||||
MergeDeclarationMarker = 319,
|
||||
EndOfDeclarationMarker = 320,
|
||||
Count = 321,
|
||||
FirstAssignment = 60,
|
||||
LastAssignment = 72,
|
||||
FirstCompoundAssignment = 61,
|
||||
LastCompoundAssignment = 72,
|
||||
FirstReservedWord = 74,
|
||||
LastReservedWord = 109,
|
||||
FirstKeyword = 74,
|
||||
LastKeyword = 149,
|
||||
FirstFutureReservedWord = 110,
|
||||
LastFutureReservedWord = 118,
|
||||
FirstTypeNode = 165,
|
||||
LastTypeNode = 185,
|
||||
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,
|
||||
FirstPunctuation = 18,
|
||||
LastPunctuation = 72,
|
||||
LastPunctuation = 73,
|
||||
FirstToken = 0,
|
||||
LastToken = 149,
|
||||
LastToken = 150,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
LastLiteralToken = 14,
|
||||
FirstTemplateToken = 14,
|
||||
LastTemplateToken = 17,
|
||||
FirstBinaryOperator = 28,
|
||||
LastBinaryOperator = 72,
|
||||
FirstStatement = 222,
|
||||
LastStatement = 238,
|
||||
FirstNode = 150,
|
||||
FirstJSDocNode = 290,
|
||||
LastJSDocNode = 314,
|
||||
FirstJSDocTagNode = 302,
|
||||
LastJSDocTagNode = 314,
|
||||
FirstBinaryOperator = 29,
|
||||
LastBinaryOperator = 73,
|
||||
FirstStatement = 223,
|
||||
LastStatement = 239,
|
||||
FirstNode = 151,
|
||||
FirstJSDocNode = 291,
|
||||
LastJSDocNode = 315,
|
||||
FirstJSDocTagNode = 303,
|
||||
LastJSDocTagNode = 315,
|
||||
}
|
||||
export enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -438,27 +440,28 @@ declare namespace ts {
|
||||
NestedNamespace = 4,
|
||||
Synthesized = 8,
|
||||
Namespace = 16,
|
||||
ExportContext = 32,
|
||||
ContainsThis = 64,
|
||||
HasImplicitReturn = 128,
|
||||
HasExplicitReturn = 256,
|
||||
GlobalAugmentation = 512,
|
||||
HasAsyncFunctions = 1024,
|
||||
DisallowInContext = 2048,
|
||||
YieldContext = 4096,
|
||||
DecoratorContext = 8192,
|
||||
AwaitContext = 16384,
|
||||
ThisNodeHasError = 32768,
|
||||
JavaScriptFile = 65536,
|
||||
ThisNodeOrAnySubNodesHasError = 131072,
|
||||
HasAggregatedChildData = 262144,
|
||||
JSDoc = 2097152,
|
||||
JsonFile = 16777216,
|
||||
OptionalChain = 32,
|
||||
ExportContext = 64,
|
||||
ContainsThis = 128,
|
||||
HasImplicitReturn = 256,
|
||||
HasExplicitReturn = 512,
|
||||
GlobalAugmentation = 1024,
|
||||
HasAsyncFunctions = 2048,
|
||||
DisallowInContext = 4096,
|
||||
YieldContext = 8192,
|
||||
DecoratorContext = 16384,
|
||||
AwaitContext = 32768,
|
||||
ThisNodeHasError = 65536,
|
||||
JavaScriptFile = 131072,
|
||||
ThisNodeOrAnySubNodesHasError = 262144,
|
||||
HasAggregatedChildData = 524288,
|
||||
JSDoc = 4194304,
|
||||
JsonFile = 33554432,
|
||||
BlockScoped = 3,
|
||||
ReachabilityCheckFlags = 384,
|
||||
ReachabilityAndEmitFlags = 1408,
|
||||
ContextFlags = 12679168,
|
||||
TypeExcludesFlags = 20480,
|
||||
ReachabilityCheckFlags = 768,
|
||||
ReachabilityAndEmitFlags = 2816,
|
||||
ContextFlags = 25358336,
|
||||
TypeExcludesFlags = 40960,
|
||||
}
|
||||
export enum ModifierFlags {
|
||||
None = 0,
|
||||
@@ -508,8 +511,10 @@ declare namespace ts {
|
||||
export interface Token<TKind extends SyntaxKind> extends Node {
|
||||
kind: TKind;
|
||||
}
|
||||
export type DotToken = Token<SyntaxKind.DotToken>;
|
||||
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
export type QuestionDotToken = Token<SyntaxKind.QuestionDotToken>;
|
||||
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
export type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
@@ -1082,8 +1087,12 @@ declare namespace ts {
|
||||
export interface PropertyAccessExpression extends MemberExpression, NamedDeclaration {
|
||||
kind: SyntaxKind.PropertyAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
name: Identifier;
|
||||
}
|
||||
export interface PropertyAccessChain extends PropertyAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
export interface SuperPropertyAccessExpression extends PropertyAccessExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -1095,8 +1104,12 @@ declare namespace ts {
|
||||
export interface ElementAccessExpression extends MemberExpression {
|
||||
kind: SyntaxKind.ElementAccessExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
argumentExpression: Expression;
|
||||
}
|
||||
export interface ElementAccessChain extends ElementAccessExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
export interface SuperElementAccessExpression extends ElementAccessExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -1104,9 +1117,14 @@ declare namespace ts {
|
||||
export interface CallExpression extends LeftHandSideExpression, Declaration {
|
||||
kind: SyntaxKind.CallExpression;
|
||||
expression: LeftHandSideExpression;
|
||||
questionDotToken?: QuestionDotToken;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
arguments: NodeArray<Expression>;
|
||||
}
|
||||
export interface CallChain extends CallExpression {
|
||||
_optionalChainBrand: any;
|
||||
}
|
||||
export type OptionalChain = PropertyAccessChain | ElementAccessChain | CallChain;
|
||||
export interface SuperCall extends CallExpression {
|
||||
expression: SuperExpression;
|
||||
}
|
||||
@@ -3496,8 +3514,12 @@ declare namespace ts {
|
||||
function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression;
|
||||
function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression;
|
||||
function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression;
|
||||
function isPropertyAccessChain(node: Node): node is PropertyAccessChain;
|
||||
function isElementAccessExpression(node: Node): node is ElementAccessExpression;
|
||||
function isElementAccessChain(node: Node): node is ElementAccessChain;
|
||||
function isCallExpression(node: Node): node is CallExpression;
|
||||
function isCallChain(node: Node): node is CallChain;
|
||||
function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain;
|
||||
function isNewExpression(node: Node): node is NewExpression;
|
||||
function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression;
|
||||
function isTypeAssertion(node: Node): node is TypeAssertion;
|
||||
@@ -3943,10 +3965,16 @@ declare namespace ts {
|
||||
function updateObjectLiteral(node: ObjectLiteralExpression, properties: readonly ObjectLiteralElementLike[]): ObjectLiteralExpression;
|
||||
function createPropertyAccess(expression: Expression, name: string | Identifier): PropertyAccessExpression;
|
||||
function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression;
|
||||
function createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, name: string | Identifier): PropertyAccessChain;
|
||||
function updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, name: Identifier): PropertyAccessChain;
|
||||
function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
function createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, index: number | Expression): ElementAccessChain;
|
||||
function updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, argumentExpression: Expression): ElementAccessChain;
|
||||
function createCall(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallExpression;
|
||||
function updateCall(node: CallExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallExpression;
|
||||
function createCallChain(expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): CallChain;
|
||||
function updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken | undefined, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[]): CallChain;
|
||||
function createNew(expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression;
|
||||
function updateNew(node: NewExpression, expression: Expression, typeArguments: readonly TypeNode[] | undefined, argumentsArray: readonly Expression[] | undefined): NewExpression;
|
||||
/** @deprecated */ function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//// [callChain.2.ts]
|
||||
declare const o1: undefined | (() => number);
|
||||
o1?.();
|
||||
|
||||
declare const o2: undefined | { b: () => number };
|
||||
o2?.b();
|
||||
|
||||
declare const o3: { b: (() => { c: string }) | undefined };
|
||||
o3.b?.().c;
|
||||
|
||||
|
||||
//// [callChain.2.js]
|
||||
var _a, _b, _c, _d;
|
||||
(_a = o1) === null || _a === void 0 ? void 0 : _a();
|
||||
(_b = o2) === null || _b === void 0 ? void 0 : _b.b();
|
||||
(_d = (_c = o3).b) === null || _d === void 0 ? void 0 : _d.call(_c).c;
|
||||
@@ -0,0 +1,28 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.2.ts ===
|
||||
declare const o1: undefined | (() => number);
|
||||
>o1 : Symbol(o1, Decl(callChain.2.ts, 0, 13))
|
||||
|
||||
o1?.();
|
||||
>o1 : Symbol(o1, Decl(callChain.2.ts, 0, 13))
|
||||
|
||||
declare const o2: undefined | { b: () => number };
|
||||
>o2 : Symbol(o2, Decl(callChain.2.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(callChain.2.ts, 3, 31))
|
||||
|
||||
o2?.b();
|
||||
>o2?.b : Symbol(b, Decl(callChain.2.ts, 3, 31))
|
||||
>o2 : Symbol(o2, Decl(callChain.2.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(callChain.2.ts, 3, 31))
|
||||
|
||||
declare const o3: { b: (() => { c: string }) | undefined };
|
||||
>o3 : Symbol(o3, Decl(callChain.2.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.2.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(callChain.2.ts, 6, 31))
|
||||
|
||||
o3.b?.().c;
|
||||
>o3.b?.().c : Symbol(c, Decl(callChain.2.ts, 6, 31))
|
||||
>o3.b : Symbol(b, Decl(callChain.2.ts, 6, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.2.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.2.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(callChain.2.ts, 6, 31))
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.2.ts ===
|
||||
declare const o1: undefined | (() => number);
|
||||
>o1 : () => number
|
||||
|
||||
o1?.();
|
||||
>o1?.() : number
|
||||
>o1 : () => number
|
||||
|
||||
declare const o2: undefined | { b: () => number };
|
||||
>o2 : { b: () => number; }
|
||||
>b : () => number
|
||||
|
||||
o2?.b();
|
||||
>o2?.b() : number
|
||||
>o2?.b : () => number
|
||||
>o2 : { b: () => number; }
|
||||
>b : () => number
|
||||
|
||||
declare const o3: { b: (() => { c: string }) | undefined };
|
||||
>o3 : { b: () => { c: string; }; }
|
||||
>b : () => { c: string; }
|
||||
>c : string
|
||||
|
||||
o3.b?.().c;
|
||||
>o3.b?.().c : string
|
||||
>o3.b?.() : { c: string; }
|
||||
>o3.b : () => { c: string; }
|
||||
>o3 : { b: () => { c: string; }; }
|
||||
>b : () => { c: string; }
|
||||
>c : string
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
tests/cases/conformance/expressions/optionalChaining/callChain/callChain.3.ts(3,7): error TS2322: Type 'number | undefined' is not assignable to type 'number'.
|
||||
Type 'undefined' is not assignable to type 'number'.
|
||||
tests/cases/conformance/expressions/optionalChaining/callChain/callChain.3.ts(4,7): error TS2322: Type 'number | undefined' is not assignable to type 'number'.
|
||||
Type 'undefined' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.3.ts (2 errors) ====
|
||||
declare function absorb<T>(): T;
|
||||
declare const a: { m?<T>(obj: {x: T}): T } | undefined;
|
||||
const n1: number = a?.m?.({x: 12 }); // should be an error (`undefined` is not assignable to `number`)
|
||||
~~
|
||||
!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
const n2: number = a?.m?.({x: absorb()}); // likewise
|
||||
~~
|
||||
!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'number'.
|
||||
const n3: number | undefined = a?.m?.({x: 12}); // should be ok
|
||||
const n4: number | undefined = a?.m?.({x: absorb()}); // likewise
|
||||
|
||||
// Also a test showing `!` vs `?` for good measure
|
||||
let t1 = a?.m?.({x: 12});
|
||||
t1 = a!.m!({x: 12});
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [callChain.3.ts]
|
||||
declare function absorb<T>(): T;
|
||||
declare const a: { m?<T>(obj: {x: T}): T } | undefined;
|
||||
const n1: number = a?.m?.({x: 12 }); // should be an error (`undefined` is not assignable to `number`)
|
||||
const n2: number = a?.m?.({x: absorb()}); // likewise
|
||||
const n3: number | undefined = a?.m?.({x: 12}); // should be ok
|
||||
const n4: number | undefined = a?.m?.({x: absorb()}); // likewise
|
||||
|
||||
// Also a test showing `!` vs `?` for good measure
|
||||
let t1 = a?.m?.({x: 12});
|
||||
t1 = a!.m!({x: 12});
|
||||
|
||||
//// [callChain.3.js]
|
||||
"use strict";
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
||||
var n1 = (_c = (_a = a) === null || _a === void 0 ? void 0 : (_b = _a).m) === null || _c === void 0 ? void 0 : _c.call(_b, { x: 12 }); // should be an error (`undefined` is not assignable to `number`)
|
||||
var n2 = (_f = (_d = a) === null || _d === void 0 ? void 0 : (_e = _d).m) === null || _f === void 0 ? void 0 : _f.call(_e, { x: absorb() }); // likewise
|
||||
var n3 = (_j = (_g = a) === null || _g === void 0 ? void 0 : (_h = _g).m) === null || _j === void 0 ? void 0 : _j.call(_h, { x: 12 }); // should be ok
|
||||
var n4 = (_m = (_k = a) === null || _k === void 0 ? void 0 : (_l = _k).m) === null || _m === void 0 ? void 0 : _m.call(_l, { x: absorb() }); // likewise
|
||||
// Also a test showing `!` vs `?` for good measure
|
||||
var t1 = (_q = (_o = a) === null || _o === void 0 ? void 0 : (_p = _o).m) === null || _q === void 0 ? void 0 : _q.call(_p, { x: 12 });
|
||||
t1 = a.m({ x: 12 });
|
||||
@@ -0,0 +1,60 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.3.ts ===
|
||||
declare function absorb<T>(): T;
|
||||
>absorb : Symbol(absorb, Decl(callChain.3.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(callChain.3.ts, 0, 24))
|
||||
>T : Symbol(T, Decl(callChain.3.ts, 0, 24))
|
||||
|
||||
declare const a: { m?<T>(obj: {x: T}): T } | undefined;
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>T : Symbol(T, Decl(callChain.3.ts, 1, 22))
|
||||
>obj : Symbol(obj, Decl(callChain.3.ts, 1, 25))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 1, 31))
|
||||
>T : Symbol(T, Decl(callChain.3.ts, 1, 22))
|
||||
>T : Symbol(T, Decl(callChain.3.ts, 1, 22))
|
||||
|
||||
const n1: number = a?.m?.({x: 12 }); // should be an error (`undefined` is not assignable to `number`)
|
||||
>n1 : Symbol(n1, Decl(callChain.3.ts, 2, 5))
|
||||
>a?.m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 2, 27))
|
||||
|
||||
const n2: number = a?.m?.({x: absorb()}); // likewise
|
||||
>n2 : Symbol(n2, Decl(callChain.3.ts, 3, 5))
|
||||
>a?.m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 3, 27))
|
||||
>absorb : Symbol(absorb, Decl(callChain.3.ts, 0, 0))
|
||||
|
||||
const n3: number | undefined = a?.m?.({x: 12}); // should be ok
|
||||
>n3 : Symbol(n3, Decl(callChain.3.ts, 4, 5))
|
||||
>a?.m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 4, 39))
|
||||
|
||||
const n4: number | undefined = a?.m?.({x: absorb()}); // likewise
|
||||
>n4 : Symbol(n4, Decl(callChain.3.ts, 5, 5))
|
||||
>a?.m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 5, 39))
|
||||
>absorb : Symbol(absorb, Decl(callChain.3.ts, 0, 0))
|
||||
|
||||
// Also a test showing `!` vs `?` for good measure
|
||||
let t1 = a?.m?.({x: 12});
|
||||
>t1 : Symbol(t1, Decl(callChain.3.ts, 8, 3))
|
||||
>a?.m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 8, 17))
|
||||
|
||||
t1 = a!.m!({x: 12});
|
||||
>t1 : Symbol(t1, Decl(callChain.3.ts, 8, 3))
|
||||
>a!.m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>a : Symbol(a, Decl(callChain.3.ts, 1, 13))
|
||||
>m : Symbol(m, Decl(callChain.3.ts, 1, 18))
|
||||
>x : Symbol(x, Decl(callChain.3.ts, 9, 12))
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.3.ts ===
|
||||
declare function absorb<T>(): T;
|
||||
>absorb : <T>() => T
|
||||
|
||||
declare const a: { m?<T>(obj: {x: T}): T } | undefined;
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>obj : { x: T; }
|
||||
>x : T
|
||||
|
||||
const n1: number = a?.m?.({x: 12 }); // should be an error (`undefined` is not assignable to `number`)
|
||||
>n1 : number
|
||||
>a?.m?.({x: 12 }) : number | undefined
|
||||
>a?.m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>{x: 12 } : { x: number; }
|
||||
>x : number
|
||||
>12 : 12
|
||||
|
||||
const n2: number = a?.m?.({x: absorb()}); // likewise
|
||||
>n2 : number
|
||||
>a?.m?.({x: absorb()}) : number | undefined
|
||||
>a?.m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>{x: absorb()} : { x: number; }
|
||||
>x : number
|
||||
>absorb() : number
|
||||
>absorb : <T>() => T
|
||||
|
||||
const n3: number | undefined = a?.m?.({x: 12}); // should be ok
|
||||
>n3 : number | undefined
|
||||
>a?.m?.({x: 12}) : number | undefined
|
||||
>a?.m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>{x: 12} : { x: number; }
|
||||
>x : number
|
||||
>12 : 12
|
||||
|
||||
const n4: number | undefined = a?.m?.({x: absorb()}); // likewise
|
||||
>n4 : number | undefined
|
||||
>a?.m?.({x: absorb()}) : number | undefined
|
||||
>a?.m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>{x: absorb()} : { x: number | undefined; }
|
||||
>x : number | undefined
|
||||
>absorb() : number | undefined
|
||||
>absorb : <T>() => T
|
||||
|
||||
// Also a test showing `!` vs `?` for good measure
|
||||
let t1 = a?.m?.({x: 12});
|
||||
>t1 : number | undefined
|
||||
>a?.m?.({x: 12}) : number | undefined
|
||||
>a?.m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>{x: 12} : { x: number; }
|
||||
>x : number
|
||||
>12 : 12
|
||||
|
||||
t1 = a!.m!({x: 12});
|
||||
>t1 = a!.m!({x: 12}) : number
|
||||
>t1 : number | undefined
|
||||
>a!.m!({x: 12}) : number
|
||||
>a!.m! : <T>(obj: { x: T; }) => T
|
||||
>a!.m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>a! : { m?<T>(obj: { x: T; }): T; }
|
||||
>a : { m?<T>(obj: { x: T; }): T; } | undefined
|
||||
>m : (<T>(obj: { x: T; }) => T) | undefined
|
||||
>{x: 12} : { x: number; }
|
||||
>x : number
|
||||
>12 : 12
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//// [callChain.ts]
|
||||
declare const o1: undefined | ((...args: any[]) => number);
|
||||
o1?.();
|
||||
o1?.(1);
|
||||
o1?.(...[1, 2]);
|
||||
o1?.(1, ...[2, 3], 4);
|
||||
|
||||
declare const o2: undefined | { b: (...args: any[]) => number };
|
||||
o2?.b();
|
||||
o2?.b(1);
|
||||
o2?.b(...[1, 2]);
|
||||
o2?.b(1, ...[2, 3], 4);
|
||||
o2?.["b"]();
|
||||
o2?.["b"](1);
|
||||
o2?.["b"](...[1, 2]);
|
||||
o2?.["b"](1, ...[2, 3], 4);
|
||||
|
||||
declare const o3: { b: ((...args: any[]) => { c: string }) | undefined };
|
||||
o3.b?.().c;
|
||||
o3.b?.(1).c;
|
||||
o3.b?.(...[1, 2]).c;
|
||||
o3.b?.(1, ...[2, 3], 4).c;
|
||||
o3.b?.()["c"];
|
||||
o3.b?.(1)["c"];
|
||||
o3.b?.(...[1, 2])["c"];
|
||||
o3.b?.(1, ...[2, 3], 4)["c"];
|
||||
o3["b"]?.().c;
|
||||
o3["b"]?.(1).c;
|
||||
o3["b"]?.(...[1, 2]).c;
|
||||
o3["b"]?.(1, ...[2, 3], 4).c;
|
||||
|
||||
declare const o4: undefined | (<T>(f: (a: T) => T) => T);
|
||||
declare function incr(x: number): number;
|
||||
const v: number | undefined = o4?.(incr);
|
||||
|
||||
//// [callChain.js]
|
||||
"use strict";
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||
r[k] = a[j];
|
||||
return r;
|
||||
};
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
|
||||
(_a = o1) === null || _a === void 0 ? void 0 : _a();
|
||||
(_b = o1) === null || _b === void 0 ? void 0 : _b(1);
|
||||
(_c = o1) === null || _c === void 0 ? void 0 : _c.apply(void 0, [1, 2]);
|
||||
(_d = o1) === null || _d === void 0 ? void 0 : _d.apply(void 0, __spreadArrays([1], [2, 3], [4]));
|
||||
(_e = o2) === null || _e === void 0 ? void 0 : _e.b();
|
||||
(_f = o2) === null || _f === void 0 ? void 0 : _f.b(1);
|
||||
(_g = o2) === null || _g === void 0 ? void 0 : _g.b.apply(_g, [1, 2]);
|
||||
(_h = o2) === null || _h === void 0 ? void 0 : _h.b.apply(_h, __spreadArrays([1], [2, 3], [4]));
|
||||
(_j = o2) === null || _j === void 0 ? void 0 : _j["b"]();
|
||||
(_k = o2) === null || _k === void 0 ? void 0 : _k["b"](1);
|
||||
(_l = o2) === null || _l === void 0 ? void 0 : _l["b"].apply(_l, [1, 2]);
|
||||
(_m = o2) === null || _m === void 0 ? void 0 : _m["b"].apply(_m, __spreadArrays([1], [2, 3], [4]));
|
||||
(_p = (_o = o3).b) === null || _p === void 0 ? void 0 : _p.call(_o).c;
|
||||
(_r = (_q = o3).b) === null || _r === void 0 ? void 0 : _r.call(_q, 1).c;
|
||||
(_t = (_s = o3).b) === null || _t === void 0 ? void 0 : _t.call.apply(_t, __spreadArrays([_s], [1, 2])).c;
|
||||
(_v = (_u = o3).b) === null || _v === void 0 ? void 0 : _v.call.apply(_v, __spreadArrays([_u, 1], [2, 3], [4])).c;
|
||||
(_x = (_w = o3).b) === null || _x === void 0 ? void 0 : _x.call(_w)["c"];
|
||||
(_z = (_y = o3).b) === null || _z === void 0 ? void 0 : _z.call(_y, 1)["c"];
|
||||
(_1 = (_0 = o3).b) === null || _1 === void 0 ? void 0 : _1.call.apply(_1, __spreadArrays([_0], [1, 2]))["c"];
|
||||
(_3 = (_2 = o3).b) === null || _3 === void 0 ? void 0 : _3.call.apply(_3, __spreadArrays([_2, 1], [2, 3], [4]))["c"];
|
||||
(_5 = (_4 = o3)["b"]) === null || _5 === void 0 ? void 0 : _5.call(_4).c;
|
||||
(_7 = (_6 = o3)["b"]) === null || _7 === void 0 ? void 0 : _7.call(_6, 1).c;
|
||||
(_9 = (_8 = o3)["b"]) === null || _9 === void 0 ? void 0 : _9.call.apply(_9, __spreadArrays([_8], [1, 2])).c;
|
||||
(_11 = (_10 = o3)["b"]) === null || _11 === void 0 ? void 0 : _11.call.apply(_11, __spreadArrays([_10, 1], [2, 3], [4])).c;
|
||||
var v = (_12 = o4) === null || _12 === void 0 ? void 0 : _12(incr);
|
||||
@@ -0,0 +1,150 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.ts ===
|
||||
declare const o1: undefined | ((...args: any[]) => number);
|
||||
>o1 : Symbol(o1, Decl(callChain.ts, 0, 13))
|
||||
>args : Symbol(args, Decl(callChain.ts, 0, 32))
|
||||
|
||||
o1?.();
|
||||
>o1 : Symbol(o1, Decl(callChain.ts, 0, 13))
|
||||
|
||||
o1?.(1);
|
||||
>o1 : Symbol(o1, Decl(callChain.ts, 0, 13))
|
||||
|
||||
o1?.(...[1, 2]);
|
||||
>o1 : Symbol(o1, Decl(callChain.ts, 0, 13))
|
||||
|
||||
o1?.(1, ...[2, 3], 4);
|
||||
>o1 : Symbol(o1, Decl(callChain.ts, 0, 13))
|
||||
|
||||
declare const o2: undefined | { b: (...args: any[]) => number };
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
>args : Symbol(args, Decl(callChain.ts, 6, 36))
|
||||
|
||||
o2?.b();
|
||||
>o2?.b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
|
||||
o2?.b(1);
|
||||
>o2?.b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
|
||||
o2?.b(...[1, 2]);
|
||||
>o2?.b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
|
||||
o2?.b(1, ...[2, 3], 4);
|
||||
>o2?.b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 6, 31))
|
||||
|
||||
o2?.["b"]();
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
|
||||
o2?.["b"](1);
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
|
||||
o2?.["b"](...[1, 2]);
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
|
||||
o2?.["b"](1, ...[2, 3], 4);
|
||||
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
|
||||
|
||||
declare const o3: { b: ((...args: any[]) => { c: string }) | undefined };
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>args : Symbol(args, Decl(callChain.ts, 16, 25))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3.b?.().c;
|
||||
>o3.b?.().c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3.b?.(1).c;
|
||||
>o3.b?.(1).c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3.b?.(...[1, 2]).c;
|
||||
>o3.b?.(...[1, 2]).c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3.b?.(1, ...[2, 3], 4).c;
|
||||
>o3.b?.(1, ...[2, 3], 4).c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3.b?.()["c"];
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
|
||||
o3.b?.(1)["c"];
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
|
||||
o3.b?.(...[1, 2])["c"];
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
|
||||
o3.b?.(1, ...[2, 3], 4)["c"];
|
||||
>o3.b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>b : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
|
||||
o3["b"]?.().c;
|
||||
>o3["b"]?.().c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>"b" : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3["b"]?.(1).c;
|
||||
>o3["b"]?.(1).c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>"b" : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3["b"]?.(...[1, 2]).c;
|
||||
>o3["b"]?.(...[1, 2]).c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>"b" : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
o3["b"]?.(1, ...[2, 3], 4).c;
|
||||
>o3["b"]?.(1, ...[2, 3], 4).c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
>o3 : Symbol(o3, Decl(callChain.ts, 16, 13))
|
||||
>"b" : Symbol(b, Decl(callChain.ts, 16, 19))
|
||||
>c : Symbol(c, Decl(callChain.ts, 16, 45))
|
||||
|
||||
declare const o4: undefined | (<T>(f: (a: T) => T) => T);
|
||||
>o4 : Symbol(o4, Decl(callChain.ts, 30, 13))
|
||||
>T : Symbol(T, Decl(callChain.ts, 30, 32))
|
||||
>f : Symbol(f, Decl(callChain.ts, 30, 35))
|
||||
>a : Symbol(a, Decl(callChain.ts, 30, 39))
|
||||
>T : Symbol(T, Decl(callChain.ts, 30, 32))
|
||||
>T : Symbol(T, Decl(callChain.ts, 30, 32))
|
||||
>T : Symbol(T, Decl(callChain.ts, 30, 32))
|
||||
|
||||
declare function incr(x: number): number;
|
||||
>incr : Symbol(incr, Decl(callChain.ts, 30, 57))
|
||||
>x : Symbol(x, Decl(callChain.ts, 31, 22))
|
||||
|
||||
const v: number | undefined = o4?.(incr);
|
||||
>v : Symbol(v, Decl(callChain.ts, 32, 5))
|
||||
>o4 : Symbol(o4, Decl(callChain.ts, 30, 13))
|
||||
>incr : Symbol(incr, Decl(callChain.ts, 30, 57))
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/callChain/callChain.ts ===
|
||||
declare const o1: undefined | ((...args: any[]) => number);
|
||||
>o1 : ((...args: any[]) => number) | undefined
|
||||
>args : any[]
|
||||
|
||||
o1?.();
|
||||
>o1?.() : number | undefined
|
||||
>o1 : ((...args: any[]) => number) | undefined
|
||||
|
||||
o1?.(1);
|
||||
>o1?.(1) : number | undefined
|
||||
>o1 : ((...args: any[]) => number) | undefined
|
||||
>1 : 1
|
||||
|
||||
o1?.(...[1, 2]);
|
||||
>o1?.(...[1, 2]) : number | undefined
|
||||
>o1 : ((...args: any[]) => number) | undefined
|
||||
>...[1, 2] : number
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
|
||||
o1?.(1, ...[2, 3], 4);
|
||||
>o1?.(1, ...[2, 3], 4) : number | undefined
|
||||
>o1 : ((...args: any[]) => number) | undefined
|
||||
>1 : 1
|
||||
>...[2, 3] : number
|
||||
>[2, 3] : number[]
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
|
||||
declare const o2: undefined | { b: (...args: any[]) => number };
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>b : (...args: any[]) => number
|
||||
>args : any[]
|
||||
|
||||
o2?.b();
|
||||
>o2?.b() : number | undefined
|
||||
>o2?.b : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>b : ((...args: any[]) => number) | undefined
|
||||
|
||||
o2?.b(1);
|
||||
>o2?.b(1) : number | undefined
|
||||
>o2?.b : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>b : ((...args: any[]) => number) | undefined
|
||||
>1 : 1
|
||||
|
||||
o2?.b(...[1, 2]);
|
||||
>o2?.b(...[1, 2]) : number | undefined
|
||||
>o2?.b : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>b : ((...args: any[]) => number) | undefined
|
||||
>...[1, 2] : number
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
|
||||
o2?.b(1, ...[2, 3], 4);
|
||||
>o2?.b(1, ...[2, 3], 4) : number | undefined
|
||||
>o2?.b : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>b : ((...args: any[]) => number) | undefined
|
||||
>1 : 1
|
||||
>...[2, 3] : number
|
||||
>[2, 3] : number[]
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
|
||||
o2?.["b"]();
|
||||
>o2?.["b"]() : number | undefined
|
||||
>o2?.["b"] : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>"b" : "b"
|
||||
|
||||
o2?.["b"](1);
|
||||
>o2?.["b"](1) : number | undefined
|
||||
>o2?.["b"] : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>"b" : "b"
|
||||
>1 : 1
|
||||
|
||||
o2?.["b"](...[1, 2]);
|
||||
>o2?.["b"](...[1, 2]) : number | undefined
|
||||
>o2?.["b"] : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>"b" : "b"
|
||||
>...[1, 2] : number
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
|
||||
o2?.["b"](1, ...[2, 3], 4);
|
||||
>o2?.["b"](1, ...[2, 3], 4) : number | undefined
|
||||
>o2?.["b"] : ((...args: any[]) => number) | undefined
|
||||
>o2 : { b: (...args: any[]) => number; } | undefined
|
||||
>"b" : "b"
|
||||
>1 : 1
|
||||
>...[2, 3] : number
|
||||
>[2, 3] : number[]
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
|
||||
declare const o3: { b: ((...args: any[]) => { c: string }) | undefined };
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>args : any[]
|
||||
>c : string
|
||||
|
||||
o3.b?.().c;
|
||||
>o3.b?.().c : string | undefined
|
||||
>o3.b?.() : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>c : string | undefined
|
||||
|
||||
o3.b?.(1).c;
|
||||
>o3.b?.(1).c : string | undefined
|
||||
>o3.b?.(1) : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>1 : 1
|
||||
>c : string | undefined
|
||||
|
||||
o3.b?.(...[1, 2]).c;
|
||||
>o3.b?.(...[1, 2]).c : string | undefined
|
||||
>o3.b?.(...[1, 2]) : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>...[1, 2] : number
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>c : string | undefined
|
||||
|
||||
o3.b?.(1, ...[2, 3], 4).c;
|
||||
>o3.b?.(1, ...[2, 3], 4).c : string | undefined
|
||||
>o3.b?.(1, ...[2, 3], 4) : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>1 : 1
|
||||
>...[2, 3] : number
|
||||
>[2, 3] : number[]
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
>c : string | undefined
|
||||
|
||||
o3.b?.()["c"];
|
||||
>o3.b?.()["c"] : string | undefined
|
||||
>o3.b?.() : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>"c" : "c"
|
||||
|
||||
o3.b?.(1)["c"];
|
||||
>o3.b?.(1)["c"] : string | undefined
|
||||
>o3.b?.(1) : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>1 : 1
|
||||
>"c" : "c"
|
||||
|
||||
o3.b?.(...[1, 2])["c"];
|
||||
>o3.b?.(...[1, 2])["c"] : string | undefined
|
||||
>o3.b?.(...[1, 2]) : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>...[1, 2] : number
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>"c" : "c"
|
||||
|
||||
o3.b?.(1, ...[2, 3], 4)["c"];
|
||||
>o3.b?.(1, ...[2, 3], 4)["c"] : string | undefined
|
||||
>o3.b?.(1, ...[2, 3], 4) : { c: string; } | undefined
|
||||
>o3.b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>b : ((...args: any[]) => { c: string; }) | undefined
|
||||
>1 : 1
|
||||
>...[2, 3] : number
|
||||
>[2, 3] : number[]
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
>"c" : "c"
|
||||
|
||||
o3["b"]?.().c;
|
||||
>o3["b"]?.().c : string | undefined
|
||||
>o3["b"]?.() : { c: string; } | undefined
|
||||
>o3["b"] : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>"b" : "b"
|
||||
>c : string | undefined
|
||||
|
||||
o3["b"]?.(1).c;
|
||||
>o3["b"]?.(1).c : string | undefined
|
||||
>o3["b"]?.(1) : { c: string; } | undefined
|
||||
>o3["b"] : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>"b" : "b"
|
||||
>1 : 1
|
||||
>c : string | undefined
|
||||
|
||||
o3["b"]?.(...[1, 2]).c;
|
||||
>o3["b"]?.(...[1, 2]).c : string | undefined
|
||||
>o3["b"]?.(...[1, 2]) : { c: string; } | undefined
|
||||
>o3["b"] : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>"b" : "b"
|
||||
>...[1, 2] : number
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>c : string | undefined
|
||||
|
||||
o3["b"]?.(1, ...[2, 3], 4).c;
|
||||
>o3["b"]?.(1, ...[2, 3], 4).c : string | undefined
|
||||
>o3["b"]?.(1, ...[2, 3], 4) : { c: string; } | undefined
|
||||
>o3["b"] : ((...args: any[]) => { c: string; }) | undefined
|
||||
>o3 : { b: ((...args: any[]) => { c: string; }) | undefined; }
|
||||
>"b" : "b"
|
||||
>1 : 1
|
||||
>...[2, 3] : number
|
||||
>[2, 3] : number[]
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
>c : string | undefined
|
||||
|
||||
declare const o4: undefined | (<T>(f: (a: T) => T) => T);
|
||||
>o4 : (<T>(f: (a: T) => T) => T) | undefined
|
||||
>f : (a: T) => T
|
||||
>a : T
|
||||
|
||||
declare function incr(x: number): number;
|
||||
>incr : (x: number) => number
|
||||
>x : number
|
||||
|
||||
const v: number | undefined = o4?.(incr);
|
||||
>v : number | undefined
|
||||
>o4?.(incr) : number | undefined
|
||||
>o4 : (<T>(f: (a: T) => T) => T) | undefined
|
||||
>incr : (x: number) => number
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(10,1): error TS2454: Variable 'a' is used before being assigned.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(14,1): error TS2454: Variable 'b' is used before being assigned.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(18,1): error TS2454: Variable 'c' is used before being assigned.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(22,1): error TS2454: Variable 'd' is used before being assigned.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(35,5): error TS2722: Cannot invoke an object which is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(39,1): error TS2722: Cannot invoke an object which is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(52,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(57,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(62,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(68,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(72,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(83,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(87,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(104,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(105,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(105,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(111,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(112,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(112,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(130,5): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(134,1): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(153,9): error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts (22 errors) ====
|
||||
// assignments in shortcutting chain
|
||||
declare const o: undefined | {
|
||||
[key: string]: any;
|
||||
[key: number]: any;
|
||||
(...args: any[]): any;
|
||||
};
|
||||
|
||||
let a: number;
|
||||
o?.[a = 1];
|
||||
a.toString();
|
||||
~
|
||||
!!! error TS2454: Variable 'a' is used before being assigned.
|
||||
|
||||
let b: number;
|
||||
o?.x[b = 1];
|
||||
b.toString();
|
||||
~
|
||||
!!! error TS2454: Variable 'b' is used before being assigned.
|
||||
|
||||
let c: number;
|
||||
o?.(c = 1)
|
||||
c.toString();
|
||||
~
|
||||
!!! error TS2454: Variable 'c' is used before being assigned.
|
||||
|
||||
let d: number;
|
||||
o?.x(d = 1);
|
||||
d.toString();
|
||||
~
|
||||
!!! error TS2454: Variable 'd' is used before being assigned.
|
||||
|
||||
// type predicates
|
||||
declare const f: undefined | ((x: any) => x is number);
|
||||
declare const x: string | number;
|
||||
if (f?.(x)) {
|
||||
x; // number
|
||||
f; // (x: any) => x is number
|
||||
f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
~
|
||||
!!! error TS2722: Cannot invoke an object which is possibly 'undefined'.
|
||||
}
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
~
|
||||
!!! error TS2722: Cannot invoke an object which is possibly 'undefined'.
|
||||
|
||||
declare const o2: { f(x: any): x is number; } | undefined;
|
||||
if (o2?.f(x)) {
|
||||
x; // number
|
||||
o2.f; // (x: any) => x is number
|
||||
o2?.f;
|
||||
o2?.f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
o2;
|
||||
o2?.f;
|
||||
o2.f;
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
x;
|
||||
o2;
|
||||
o2?.f;
|
||||
o2.f;
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
declare const o3: { x: 1, y: string } | { x: 2, y: number } | undefined;
|
||||
if (o3?.x === 1) {
|
||||
o3; // TODO: should be `{ x: y, y: string }`
|
||||
o3.x; // TODO: should not be an error.
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
o3?.x;
|
||||
}
|
||||
else {
|
||||
o3;
|
||||
o3?.x;
|
||||
o3.x;
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
o3;
|
||||
o3?.x;
|
||||
o3.x;
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
declare const o4: { x?: { y: boolean } };
|
||||
if (o4.x?.y) {
|
||||
o4.x; // { y: boolean }
|
||||
o4.x.y; // true
|
||||
o4.x?.y; // true
|
||||
}
|
||||
else {
|
||||
o4.x;
|
||||
o4.x?.y;
|
||||
o4.x.y;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
o4.x;
|
||||
o4.x?.y;
|
||||
o4.x.y;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
declare const o5: { x?: { y: { z?: { w: boolean } } } };
|
||||
if (o5.x?.y.z?.w) {
|
||||
o5.x;
|
||||
o5.x.y;
|
||||
o5.x.y.z;
|
||||
o5.x.y.z.w; // true
|
||||
o5.x.y.z?.w; // true
|
||||
o5.x?.y.z.w; // true
|
||||
o5.x?.y.z?.w; // true
|
||||
}
|
||||
else {
|
||||
o5.x;
|
||||
o5.x?.y;
|
||||
o5.x?.y.z;
|
||||
o5.x?.y.z?.w;
|
||||
o5.x.y;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
o5.x.y.z.w;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~~~~~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
o5.x;
|
||||
o5.x?.y;
|
||||
o5.x?.y.z;
|
||||
o5.x?.y.z?.w;
|
||||
o5.x.y;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
o5.x.y.z.w;
|
||||
~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
~~~~~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
interface Base {
|
||||
f(): this is Derived;
|
||||
}
|
||||
|
||||
interface Derived extends Base {
|
||||
x: number;
|
||||
}
|
||||
|
||||
declare const o6: Base | undefined;
|
||||
if (o6?.f()) {
|
||||
o6; // Derived
|
||||
o6.f;
|
||||
}
|
||||
else {
|
||||
o6;
|
||||
o6?.f;
|
||||
o6.f;
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
o6;
|
||||
o6?.f;
|
||||
o6.f;
|
||||
~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
// asserts
|
||||
declare const isDefined: <T>(value: T) => asserts value is NonNullable<T>;
|
||||
declare const isString: (value: unknown) => asserts value is string;
|
||||
declare const maybeIsString: undefined | ((value: unknown) => asserts value is string);
|
||||
declare const maybeNever: undefined | (() => never);
|
||||
|
||||
function f01(x: unknown) {
|
||||
if (!!true) {
|
||||
isString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
maybeIsString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
isDefined(maybeIsString);
|
||||
maybeIsString?.(x);
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
maybeNever?.();
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
//// [controlFlowOptionalChain.ts]
|
||||
// assignments in shortcutting chain
|
||||
declare const o: undefined | {
|
||||
[key: string]: any;
|
||||
[key: number]: any;
|
||||
(...args: any[]): any;
|
||||
};
|
||||
|
||||
let a: number;
|
||||
o?.[a = 1];
|
||||
a.toString();
|
||||
|
||||
let b: number;
|
||||
o?.x[b = 1];
|
||||
b.toString();
|
||||
|
||||
let c: number;
|
||||
o?.(c = 1)
|
||||
c.toString();
|
||||
|
||||
let d: number;
|
||||
o?.x(d = 1);
|
||||
d.toString();
|
||||
|
||||
// type predicates
|
||||
declare const f: undefined | ((x: any) => x is number);
|
||||
declare const x: string | number;
|
||||
if (f?.(x)) {
|
||||
x; // number
|
||||
f; // (x: any) => x is number
|
||||
f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
}
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
|
||||
declare const o2: { f(x: any): x is number; } | undefined;
|
||||
if (o2?.f(x)) {
|
||||
x; // number
|
||||
o2.f; // (x: any) => x is number
|
||||
o2?.f;
|
||||
o2?.f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
o2;
|
||||
o2?.f;
|
||||
o2.f;
|
||||
}
|
||||
x;
|
||||
o2;
|
||||
o2?.f;
|
||||
o2.f;
|
||||
|
||||
declare const o3: { x: 1, y: string } | { x: 2, y: number } | undefined;
|
||||
if (o3?.x === 1) {
|
||||
o3; // TODO: should be `{ x: y, y: string }`
|
||||
o3.x; // TODO: should not be an error.
|
||||
o3?.x;
|
||||
}
|
||||
else {
|
||||
o3;
|
||||
o3?.x;
|
||||
o3.x;
|
||||
}
|
||||
o3;
|
||||
o3?.x;
|
||||
o3.x;
|
||||
|
||||
declare const o4: { x?: { y: boolean } };
|
||||
if (o4.x?.y) {
|
||||
o4.x; // { y: boolean }
|
||||
o4.x.y; // true
|
||||
o4.x?.y; // true
|
||||
}
|
||||
else {
|
||||
o4.x;
|
||||
o4.x?.y;
|
||||
o4.x.y;
|
||||
}
|
||||
o4.x;
|
||||
o4.x?.y;
|
||||
o4.x.y;
|
||||
|
||||
declare const o5: { x?: { y: { z?: { w: boolean } } } };
|
||||
if (o5.x?.y.z?.w) {
|
||||
o5.x;
|
||||
o5.x.y;
|
||||
o5.x.y.z;
|
||||
o5.x.y.z.w; // true
|
||||
o5.x.y.z?.w; // true
|
||||
o5.x?.y.z.w; // true
|
||||
o5.x?.y.z?.w; // true
|
||||
}
|
||||
else {
|
||||
o5.x;
|
||||
o5.x?.y;
|
||||
o5.x?.y.z;
|
||||
o5.x?.y.z?.w;
|
||||
o5.x.y;
|
||||
o5.x.y.z.w;
|
||||
}
|
||||
o5.x;
|
||||
o5.x?.y;
|
||||
o5.x?.y.z;
|
||||
o5.x?.y.z?.w;
|
||||
o5.x.y;
|
||||
o5.x.y.z.w;
|
||||
|
||||
interface Base {
|
||||
f(): this is Derived;
|
||||
}
|
||||
|
||||
interface Derived extends Base {
|
||||
x: number;
|
||||
}
|
||||
|
||||
declare const o6: Base | undefined;
|
||||
if (o6?.f()) {
|
||||
o6; // Derived
|
||||
o6.f;
|
||||
}
|
||||
else {
|
||||
o6;
|
||||
o6?.f;
|
||||
o6.f;
|
||||
}
|
||||
o6;
|
||||
o6?.f;
|
||||
o6.f;
|
||||
|
||||
// asserts
|
||||
declare const isDefined: <T>(value: T) => asserts value is NonNullable<T>;
|
||||
declare const isString: (value: unknown) => asserts value is string;
|
||||
declare const maybeIsString: undefined | ((value: unknown) => asserts value is string);
|
||||
declare const maybeNever: undefined | (() => never);
|
||||
|
||||
function f01(x: unknown) {
|
||||
if (!!true) {
|
||||
isString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
maybeIsString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
isDefined(maybeIsString);
|
||||
maybeIsString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
maybeNever?.();
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [controlFlowOptionalChain.js]
|
||||
"use strict";
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
|
||||
var a;
|
||||
(_a = o) === null || _a === void 0 ? void 0 : _a[a = 1];
|
||||
a.toString();
|
||||
var b;
|
||||
(_b = o) === null || _b === void 0 ? void 0 : _b.x[b = 1];
|
||||
b.toString();
|
||||
var c;
|
||||
(_c = o) === null || _c === void 0 ? void 0 : _c(c = 1);
|
||||
c.toString();
|
||||
var d;
|
||||
(_d = o) === null || _d === void 0 ? void 0 : _d.x(d = 1);
|
||||
d.toString();
|
||||
if ((_e = f) === null || _e === void 0 ? void 0 : _e(x)) {
|
||||
x; // number
|
||||
f; // (x: any) => x is number
|
||||
f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
}
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
if ((_f = o2) === null || _f === void 0 ? void 0 : _f.f(x)) {
|
||||
x; // number
|
||||
o2.f; // (x: any) => x is number
|
||||
(_g = o2) === null || _g === void 0 ? void 0 : _g.f;
|
||||
(_h = o2) === null || _h === void 0 ? void 0 : _h.f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
o2;
|
||||
(_j = o2) === null || _j === void 0 ? void 0 : _j.f;
|
||||
o2.f;
|
||||
}
|
||||
x;
|
||||
o2;
|
||||
(_k = o2) === null || _k === void 0 ? void 0 : _k.f;
|
||||
o2.f;
|
||||
if (((_l = o3) === null || _l === void 0 ? void 0 : _l.x) === 1) {
|
||||
o3; // TODO: should be `{ x: y, y: string }`
|
||||
o3.x; // TODO: should not be an error.
|
||||
(_m = o3) === null || _m === void 0 ? void 0 : _m.x;
|
||||
}
|
||||
else {
|
||||
o3;
|
||||
(_o = o3) === null || _o === void 0 ? void 0 : _o.x;
|
||||
o3.x;
|
||||
}
|
||||
o3;
|
||||
(_p = o3) === null || _p === void 0 ? void 0 : _p.x;
|
||||
o3.x;
|
||||
if ((_q = o4.x) === null || _q === void 0 ? void 0 : _q.y) {
|
||||
o4.x; // { y: boolean }
|
||||
o4.x.y; // true
|
||||
(_r = o4.x) === null || _r === void 0 ? void 0 : _r.y; // true
|
||||
}
|
||||
else {
|
||||
o4.x;
|
||||
(_s = o4.x) === null || _s === void 0 ? void 0 : _s.y;
|
||||
o4.x.y;
|
||||
}
|
||||
o4.x;
|
||||
(_t = o4.x) === null || _t === void 0 ? void 0 : _t.y;
|
||||
o4.x.y;
|
||||
if ((_v = (_u = o5.x) === null || _u === void 0 ? void 0 : _u.y.z) === null || _v === void 0 ? void 0 : _v.w) {
|
||||
o5.x;
|
||||
o5.x.y;
|
||||
o5.x.y.z;
|
||||
o5.x.y.z.w; // true
|
||||
(_w = o5.x.y.z) === null || _w === void 0 ? void 0 : _w.w; // true
|
||||
(_x = o5.x) === null || _x === void 0 ? void 0 : _x.y.z.w; // true
|
||||
(_z = (_y = o5.x) === null || _y === void 0 ? void 0 : _y.y.z) === null || _z === void 0 ? void 0 : _z.w; // true
|
||||
}
|
||||
else {
|
||||
o5.x;
|
||||
(_0 = o5.x) === null || _0 === void 0 ? void 0 : _0.y;
|
||||
(_1 = o5.x) === null || _1 === void 0 ? void 0 : _1.y.z;
|
||||
(_3 = (_2 = o5.x) === null || _2 === void 0 ? void 0 : _2.y.z) === null || _3 === void 0 ? void 0 : _3.w;
|
||||
o5.x.y;
|
||||
o5.x.y.z.w;
|
||||
}
|
||||
o5.x;
|
||||
(_4 = o5.x) === null || _4 === void 0 ? void 0 : _4.y;
|
||||
(_5 = o5.x) === null || _5 === void 0 ? void 0 : _5.y.z;
|
||||
(_7 = (_6 = o5.x) === null || _6 === void 0 ? void 0 : _6.y.z) === null || _7 === void 0 ? void 0 : _7.w;
|
||||
o5.x.y;
|
||||
o5.x.y.z.w;
|
||||
if ((_8 = o6) === null || _8 === void 0 ? void 0 : _8.f()) {
|
||||
o6; // Derived
|
||||
o6.f;
|
||||
}
|
||||
else {
|
||||
o6;
|
||||
(_9 = o6) === null || _9 === void 0 ? void 0 : _9.f;
|
||||
o6.f;
|
||||
}
|
||||
o6;
|
||||
(_10 = o6) === null || _10 === void 0 ? void 0 : _10.f;
|
||||
o6.f;
|
||||
function f01(x) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!!true) {
|
||||
(_a = isString) === null || _a === void 0 ? void 0 : _a(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
(_b = maybeIsString) === null || _b === void 0 ? void 0 : _b(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
isDefined(maybeIsString);
|
||||
(_c = maybeIsString) === null || _c === void 0 ? void 0 : _c(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
(_d = maybeNever) === null || _d === void 0 ? void 0 : _d();
|
||||
x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,602 @@
|
||||
=== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts ===
|
||||
// assignments in shortcutting chain
|
||||
declare const o: undefined | {
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 1, 13))
|
||||
|
||||
[key: string]: any;
|
||||
>key : Symbol(key, Decl(controlFlowOptionalChain.ts, 2, 5))
|
||||
|
||||
[key: number]: any;
|
||||
>key : Symbol(key, Decl(controlFlowOptionalChain.ts, 3, 5))
|
||||
|
||||
(...args: any[]): any;
|
||||
>args : Symbol(args, Decl(controlFlowOptionalChain.ts, 4, 5))
|
||||
|
||||
};
|
||||
|
||||
let a: number;
|
||||
>a : Symbol(a, Decl(controlFlowOptionalChain.ts, 7, 3))
|
||||
|
||||
o?.[a = 1];
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 1, 13))
|
||||
>a : Symbol(a, Decl(controlFlowOptionalChain.ts, 7, 3))
|
||||
|
||||
a.toString();
|
||||
>a.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(controlFlowOptionalChain.ts, 7, 3))
|
||||
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
let b: number;
|
||||
>b : Symbol(b, Decl(controlFlowOptionalChain.ts, 11, 3))
|
||||
|
||||
o?.x[b = 1];
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 1, 13))
|
||||
>b : Symbol(b, Decl(controlFlowOptionalChain.ts, 11, 3))
|
||||
|
||||
b.toString();
|
||||
>b.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
>b : Symbol(b, Decl(controlFlowOptionalChain.ts, 11, 3))
|
||||
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
let c: number;
|
||||
>c : Symbol(c, Decl(controlFlowOptionalChain.ts, 15, 3))
|
||||
|
||||
o?.(c = 1)
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 1, 13))
|
||||
>c : Symbol(c, Decl(controlFlowOptionalChain.ts, 15, 3))
|
||||
|
||||
c.toString();
|
||||
>c.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
>c : Symbol(c, Decl(controlFlowOptionalChain.ts, 15, 3))
|
||||
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
let d: number;
|
||||
>d : Symbol(d, Decl(controlFlowOptionalChain.ts, 19, 3))
|
||||
|
||||
o?.x(d = 1);
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 1, 13))
|
||||
>d : Symbol(d, Decl(controlFlowOptionalChain.ts, 19, 3))
|
||||
|
||||
d.toString();
|
||||
>d.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
>d : Symbol(d, Decl(controlFlowOptionalChain.ts, 19, 3))
|
||||
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
// type predicates
|
||||
declare const f: undefined | ((x: any) => x is number);
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 24, 31))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 24, 31))
|
||||
|
||||
declare const x: string | number;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
if (f?.(x)) {
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
x; // number
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
f; // (x: any) => x is number
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
|
||||
f(x);
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
}
|
||||
else {
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
f;
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
|
||||
f(x);
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
}
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
f;
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
|
||||
f(x);
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 24, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
declare const o2: { f(x: any): x is number; } | undefined;
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 40, 22))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 40, 22))
|
||||
|
||||
if (o2?.f(x)) {
|
||||
>o2?.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
x; // number
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
o2.f; // (x: any) => x is number
|
||||
>o2.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
|
||||
o2?.f;
|
||||
>o2?.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
|
||||
o2?.f(x);
|
||||
>o2?.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
}
|
||||
else {
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
o2;
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
|
||||
o2?.f;
|
||||
>o2?.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
|
||||
o2.f;
|
||||
>o2.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
}
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 25, 13))
|
||||
|
||||
o2;
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
|
||||
o2?.f;
|
||||
>o2?.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
|
||||
o2.f;
|
||||
>o2.f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
>o2 : Symbol(o2, Decl(controlFlowOptionalChain.ts, 40, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 40, 19))
|
||||
|
||||
declare const o3: { x: 1, y: string } | { x: 2, y: number } | undefined;
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 58, 25))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 58, 47))
|
||||
|
||||
if (o3?.x === 1) {
|
||||
>o3?.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
|
||||
o3; // TODO: should be `{ x: y, y: string }`
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
|
||||
o3.x; // TODO: should not be an error.
|
||||
>o3.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
|
||||
o3?.x;
|
||||
>o3?.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
}
|
||||
else {
|
||||
o3;
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
|
||||
o3?.x;
|
||||
>o3?.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
|
||||
o3.x;
|
||||
>o3.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
}
|
||||
o3;
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
|
||||
o3?.x;
|
||||
>o3?.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
|
||||
o3.x;
|
||||
>o3.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
>o3 : Symbol(o3, Decl(controlFlowOptionalChain.ts, 58, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 58, 19), Decl(controlFlowOptionalChain.ts, 58, 41))
|
||||
|
||||
declare const o4: { x?: { y: boolean } };
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
|
||||
if (o4.x?.y) {
|
||||
>o4.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
|
||||
o4.x; // { y: boolean }
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
|
||||
o4.x.y; // true
|
||||
>o4.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
|
||||
o4.x?.y; // true
|
||||
>o4.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
}
|
||||
else {
|
||||
o4.x;
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
|
||||
o4.x?.y;
|
||||
>o4.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
|
||||
o4.x.y;
|
||||
>o4.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
}
|
||||
o4.x;
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
|
||||
o4.x?.y;
|
||||
>o4.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
|
||||
o4.x.y;
|
||||
>o4.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
>o4.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>o4 : Symbol(o4, Decl(controlFlowOptionalChain.ts, 73, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 73, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 73, 25))
|
||||
|
||||
declare const o5: { x?: { y: { z?: { w: boolean } } } };
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
if (o5.x?.y.z?.w) {
|
||||
>o5.x?.y.z?.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
o5.x;
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
|
||||
o5.x.y;
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
|
||||
o5.x.y.z;
|
||||
>o5.x.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
|
||||
o5.x.y.z.w; // true
|
||||
>o5.x.y.z.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
o5.x.y.z?.w; // true
|
||||
>o5.x.y.z?.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
o5.x?.y.z.w; // true
|
||||
>o5.x?.y.z.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
o5.x?.y.z?.w; // true
|
||||
>o5.x?.y.z?.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
}
|
||||
else {
|
||||
o5.x;
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
|
||||
o5.x?.y;
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
|
||||
o5.x?.y.z;
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
|
||||
o5.x?.y.z?.w;
|
||||
>o5.x?.y.z?.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
o5.x.y;
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
|
||||
o5.x.y.z.w;
|
||||
>o5.x.y.z.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
}
|
||||
o5.x;
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
|
||||
o5.x?.y;
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
|
||||
o5.x?.y.z;
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
|
||||
o5.x?.y.z?.w;
|
||||
>o5.x?.y.z?.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x?.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x?.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
o5.x.y;
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
|
||||
o5.x.y.z.w;
|
||||
>o5.x.y.z.w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
>o5.x.y.z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>o5.x.y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>o5.x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>o5 : Symbol(o5, Decl(controlFlowOptionalChain.ts, 88, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 88, 19))
|
||||
>y : Symbol(y, Decl(controlFlowOptionalChain.ts, 88, 25))
|
||||
>z : Symbol(z, Decl(controlFlowOptionalChain.ts, 88, 30))
|
||||
>w : Symbol(w, Decl(controlFlowOptionalChain.ts, 88, 36))
|
||||
|
||||
interface Base {
|
||||
>Base : Symbol(Base, Decl(controlFlowOptionalChain.ts, 111, 11))
|
||||
|
||||
f(): this is Derived;
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>Derived : Symbol(Derived, Decl(controlFlowOptionalChain.ts, 115, 1))
|
||||
}
|
||||
|
||||
interface Derived extends Base {
|
||||
>Derived : Symbol(Derived, Decl(controlFlowOptionalChain.ts, 115, 1))
|
||||
>Base : Symbol(Base, Decl(controlFlowOptionalChain.ts, 111, 11))
|
||||
|
||||
x: number;
|
||||
>x : Symbol(Derived.x, Decl(controlFlowOptionalChain.ts, 117, 32))
|
||||
}
|
||||
|
||||
declare const o6: Base | undefined;
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>Base : Symbol(Base, Decl(controlFlowOptionalChain.ts, 111, 11))
|
||||
|
||||
if (o6?.f()) {
|
||||
>o6?.f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
|
||||
o6; // Derived
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
|
||||
o6.f;
|
||||
>o6.f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
}
|
||||
else {
|
||||
o6;
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
|
||||
o6?.f;
|
||||
>o6?.f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
|
||||
o6.f;
|
||||
>o6.f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
}
|
||||
o6;
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
|
||||
o6?.f;
|
||||
>o6?.f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
|
||||
o6.f;
|
||||
>o6.f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
>o6 : Symbol(o6, Decl(controlFlowOptionalChain.ts, 121, 13))
|
||||
>f : Symbol(Base.f, Decl(controlFlowOptionalChain.ts, 113, 16))
|
||||
|
||||
// asserts
|
||||
declare const isDefined: <T>(value: T) => asserts value is NonNullable<T>;
|
||||
>isDefined : Symbol(isDefined, Decl(controlFlowOptionalChain.ts, 136, 13))
|
||||
>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 136, 26))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 136, 29))
|
||||
>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 136, 26))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 136, 29))
|
||||
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 136, 26))
|
||||
|
||||
declare const isString: (value: unknown) => asserts value is string;
|
||||
>isString : Symbol(isString, Decl(controlFlowOptionalChain.ts, 137, 13))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 137, 25))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 137, 25))
|
||||
|
||||
declare const maybeIsString: undefined | ((value: unknown) => asserts value is string);
|
||||
>maybeIsString : Symbol(maybeIsString, Decl(controlFlowOptionalChain.ts, 138, 13))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 138, 43))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 138, 43))
|
||||
|
||||
declare const maybeNever: undefined | (() => never);
|
||||
>maybeNever : Symbol(maybeNever, Decl(controlFlowOptionalChain.ts, 139, 13))
|
||||
|
||||
function f01(x: unknown) {
|
||||
>f01 : Symbol(f01, Decl(controlFlowOptionalChain.ts, 139, 52))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
|
||||
if (!!true) {
|
||||
isString?.(x);
|
||||
>isString : Symbol(isString, Decl(controlFlowOptionalChain.ts, 137, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
}
|
||||
if (!!true) {
|
||||
maybeIsString?.(x);
|
||||
>maybeIsString : Symbol(maybeIsString, Decl(controlFlowOptionalChain.ts, 138, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
}
|
||||
if (!!true) {
|
||||
isDefined(maybeIsString);
|
||||
>isDefined : Symbol(isDefined, Decl(controlFlowOptionalChain.ts, 136, 13))
|
||||
>maybeIsString : Symbol(maybeIsString, Decl(controlFlowOptionalChain.ts, 138, 13))
|
||||
|
||||
maybeIsString?.(x);
|
||||
>maybeIsString : Symbol(maybeIsString, Decl(controlFlowOptionalChain.ts, 138, 13))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
}
|
||||
if (!!true) {
|
||||
maybeNever?.();
|
||||
>maybeNever : Symbol(maybeNever, Decl(controlFlowOptionalChain.ts, 139, 13))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 141, 13))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,636 @@
|
||||
=== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts ===
|
||||
// assignments in shortcutting chain
|
||||
declare const o: undefined | {
|
||||
>o : { (...args: any[]): any; [key: string]: any; [key: number]: any; } | undefined
|
||||
|
||||
[key: string]: any;
|
||||
>key : string
|
||||
|
||||
[key: number]: any;
|
||||
>key : number
|
||||
|
||||
(...args: any[]): any;
|
||||
>args : any[]
|
||||
|
||||
};
|
||||
|
||||
let a: number;
|
||||
>a : number
|
||||
|
||||
o?.[a = 1];
|
||||
>o?.[a = 1] : any
|
||||
>o : { (...args: any[]): any; [key: string]: any; [key: number]: any; } | undefined
|
||||
>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
|
||||
|
||||
let b: number;
|
||||
>b : number
|
||||
|
||||
o?.x[b = 1];
|
||||
>o?.x[b = 1] : any
|
||||
>o?.x : any
|
||||
>o : { (...args: any[]): any; [key: string]: any; [key: number]: any; } | undefined
|
||||
>x : any
|
||||
>b = 1 : 1
|
||||
>b : number
|
||||
>1 : 1
|
||||
|
||||
b.toString();
|
||||
>b.toString() : string
|
||||
>b.toString : (radix?: number | undefined) => string
|
||||
>b : number
|
||||
>toString : (radix?: number | undefined) => string
|
||||
|
||||
let c: number;
|
||||
>c : number
|
||||
|
||||
o?.(c = 1)
|
||||
>o?.(c = 1) : any
|
||||
>o : { (...args: any[]): any; [key: string]: any; [key: number]: any; } | undefined
|
||||
>c = 1 : 1
|
||||
>c : number
|
||||
>1 : 1
|
||||
|
||||
c.toString();
|
||||
>c.toString() : string
|
||||
>c.toString : (radix?: number | undefined) => string
|
||||
>c : number
|
||||
>toString : (radix?: number | undefined) => string
|
||||
|
||||
let d: number;
|
||||
>d : number
|
||||
|
||||
o?.x(d = 1);
|
||||
>o?.x(d = 1) : any
|
||||
>o?.x : any
|
||||
>o : { (...args: any[]): any; [key: string]: any; [key: number]: any; } | undefined
|
||||
>x : any
|
||||
>d = 1 : 1
|
||||
>d : number
|
||||
>1 : 1
|
||||
|
||||
d.toString();
|
||||
>d.toString() : string
|
||||
>d.toString : (radix?: number | undefined) => string
|
||||
>d : number
|
||||
>toString : (radix?: number | undefined) => string
|
||||
|
||||
// type predicates
|
||||
declare const f: undefined | ((x: any) => x is number);
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
>x : any
|
||||
|
||||
declare const x: string | number;
|
||||
>x : string | number
|
||||
|
||||
if (f?.(x)) {
|
||||
>f?.(x) : boolean | undefined
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
>x : string | number
|
||||
|
||||
x; // number
|
||||
>x : number
|
||||
|
||||
f; // (x: any) => x is number
|
||||
>f : (x: any) => x is number
|
||||
|
||||
f(x);
|
||||
>f(x) : boolean
|
||||
>f : (x: any) => x is number
|
||||
>x : number
|
||||
}
|
||||
else {
|
||||
x;
|
||||
>x : string | number
|
||||
|
||||
f;
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
|
||||
f(x);
|
||||
>f(x) : boolean
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
>x : string | number
|
||||
}
|
||||
x;
|
||||
>x : string | number
|
||||
|
||||
f;
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
|
||||
f(x);
|
||||
>f(x) : boolean
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
>x : string | number
|
||||
|
||||
declare const o2: { f(x: any): x is number; } | undefined;
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
>f : (x: any) => x is number
|
||||
>x : any
|
||||
|
||||
if (o2?.f(x)) {
|
||||
>o2?.f(x) : boolean | undefined
|
||||
>o2?.f : ((x: any) => x is number) | undefined
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
>x : string | number
|
||||
|
||||
x; // number
|
||||
>x : number
|
||||
|
||||
o2.f; // (x: any) => x is number
|
||||
>o2.f : (x: any) => x is number
|
||||
>o2 : { f(x: any): x is number; }
|
||||
>f : (x: any) => x is number
|
||||
|
||||
o2?.f;
|
||||
>o2?.f : (x: any) => x is number
|
||||
>o2 : { f(x: any): x is number; }
|
||||
>f : (x: any) => x is number
|
||||
|
||||
o2?.f(x);
|
||||
>o2?.f(x) : boolean
|
||||
>o2?.f : (x: any) => x is number
|
||||
>o2 : { f(x: any): x is number; }
|
||||
>f : (x: any) => x is number
|
||||
>x : number
|
||||
}
|
||||
else {
|
||||
x;
|
||||
>x : string | number
|
||||
|
||||
o2;
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
|
||||
o2?.f;
|
||||
>o2?.f : ((x: any) => x is number) | undefined
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
|
||||
o2.f;
|
||||
>o2.f : (x: any) => x is number
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
>f : (x: any) => x is number
|
||||
}
|
||||
x;
|
||||
>x : string | number
|
||||
|
||||
o2;
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
|
||||
o2?.f;
|
||||
>o2?.f : ((x: any) => x is number) | undefined
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
>f : ((x: any) => x is number) | undefined
|
||||
|
||||
o2.f;
|
||||
>o2.f : (x: any) => x is number
|
||||
>o2 : { f(x: any): x is number; } | undefined
|
||||
>f : (x: any) => x is number
|
||||
|
||||
declare const o3: { x: 1, y: string } | { x: 2, y: number } | undefined;
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 1
|
||||
>y : string
|
||||
>x : 2
|
||||
>y : number
|
||||
|
||||
if (o3?.x === 1) {
|
||||
>o3?.x === 1 : boolean
|
||||
>o3?.x : 1 | 2 | undefined
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 1 | 2 | undefined
|
||||
>1 : 1
|
||||
|
||||
o3; // TODO: should be `{ x: y, y: string }`
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
|
||||
o3.x; // TODO: should not be an error.
|
||||
>o3.x : 1
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 1
|
||||
|
||||
o3?.x;
|
||||
>o3?.x : 1 | undefined
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 1 | undefined
|
||||
}
|
||||
else {
|
||||
o3;
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
|
||||
o3?.x;
|
||||
>o3?.x : 2 | undefined
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 2 | undefined
|
||||
|
||||
o3.x;
|
||||
>o3.x : 2
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 2
|
||||
}
|
||||
o3;
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
|
||||
o3?.x;
|
||||
>o3?.x : 1 | 2 | undefined
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 1 | 2 | undefined
|
||||
|
||||
o3.x;
|
||||
>o3.x : 1 | 2
|
||||
>o3 : { x: 1; y: string; } | { x: 2; y: number; } | undefined
|
||||
>x : 1 | 2
|
||||
|
||||
declare const o4: { x?: { y: boolean } };
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
>y : boolean
|
||||
|
||||
if (o4.x?.y) {
|
||||
>o4.x?.y : boolean | undefined
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
>y : boolean | undefined
|
||||
|
||||
o4.x; // { y: boolean }
|
||||
>o4.x : { y: boolean; }
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; }
|
||||
|
||||
o4.x.y; // true
|
||||
>o4.x.y : true
|
||||
>o4.x : { y: boolean; }
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; }
|
||||
>y : true
|
||||
|
||||
o4.x?.y; // true
|
||||
>o4.x?.y : true
|
||||
>o4.x : { y: boolean; }
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; }
|
||||
>y : true
|
||||
}
|
||||
else {
|
||||
o4.x;
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
|
||||
o4.x?.y;
|
||||
>o4.x?.y : boolean | undefined
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
>y : boolean | undefined
|
||||
|
||||
o4.x.y;
|
||||
>o4.x.y : boolean
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
>y : boolean
|
||||
}
|
||||
o4.x;
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
|
||||
o4.x?.y;
|
||||
>o4.x?.y : boolean | undefined
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
>y : boolean | undefined
|
||||
|
||||
o4.x.y;
|
||||
>o4.x.y : boolean
|
||||
>o4.x : { y: boolean; } | undefined
|
||||
>o4 : { x?: { y: boolean; } | undefined; }
|
||||
>x : { y: boolean; } | undefined
|
||||
>y : boolean
|
||||
|
||||
declare const o5: { x?: { y: { z?: { w: boolean } } } };
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; } | undefined
|
||||
>w : boolean
|
||||
|
||||
if (o5.x?.y.z?.w) {
|
||||
>o5.x?.y.z?.w : boolean | undefined
|
||||
>o5.x?.y.z : { w: boolean; } | undefined
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>z : { w: boolean; } | undefined
|
||||
>w : boolean | undefined
|
||||
|
||||
o5.x;
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
|
||||
o5.x.y;
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
|
||||
o5.x.y.z;
|
||||
>o5.x.y.z : { w: boolean; }
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; }
|
||||
|
||||
o5.x.y.z.w; // true
|
||||
>o5.x.y.z.w : true
|
||||
>o5.x.y.z : { w: boolean; }
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; }
|
||||
>w : true
|
||||
|
||||
o5.x.y.z?.w; // true
|
||||
>o5.x.y.z?.w : true
|
||||
>o5.x.y.z : { w: boolean; }
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; }
|
||||
>w : true
|
||||
|
||||
o5.x?.y.z.w; // true
|
||||
>o5.x?.y.z.w : true
|
||||
>o5.x?.y.z : { w: boolean; }
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; }
|
||||
>w : true
|
||||
|
||||
o5.x?.y.z?.w; // true
|
||||
>o5.x?.y.z?.w : true
|
||||
>o5.x?.y.z : { w: boolean; }
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; }
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; }
|
||||
>w : true
|
||||
}
|
||||
else {
|
||||
o5.x;
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
|
||||
o5.x?.y;
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
|
||||
o5.x?.y.z;
|
||||
>o5.x?.y.z : { w: boolean; } | undefined
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>z : { w: boolean; } | undefined
|
||||
|
||||
o5.x?.y.z?.w;
|
||||
>o5.x?.y.z?.w : boolean | undefined
|
||||
>o5.x?.y.z : { w: boolean; } | undefined
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>z : { w: boolean; } | undefined
|
||||
>w : boolean | undefined
|
||||
|
||||
o5.x.y;
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
|
||||
o5.x.y.z.w;
|
||||
>o5.x.y.z.w : boolean
|
||||
>o5.x.y.z : { w: boolean; } | undefined
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; } | undefined
|
||||
>w : boolean
|
||||
}
|
||||
o5.x;
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
|
||||
o5.x?.y;
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
|
||||
o5.x?.y.z;
|
||||
>o5.x?.y.z : { w: boolean; } | undefined
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>z : { w: boolean; } | undefined
|
||||
|
||||
o5.x?.y.z?.w;
|
||||
>o5.x?.y.z?.w : boolean | undefined
|
||||
>o5.x?.y.z : { w: boolean; } | undefined
|
||||
>o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; } | undefined
|
||||
>z : { w: boolean; } | undefined
|
||||
>w : boolean | undefined
|
||||
|
||||
o5.x.y;
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
|
||||
o5.x.y.z.w;
|
||||
>o5.x.y.z.w : boolean
|
||||
>o5.x.y.z : { w: boolean; } | undefined
|
||||
>o5.x.y : { z?: { w: boolean; } | undefined; }
|
||||
>o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; }
|
||||
>x : { y: { z?: { w: boolean; } | undefined; }; } | undefined
|
||||
>y : { z?: { w: boolean; } | undefined; }
|
||||
>z : { w: boolean; } | undefined
|
||||
>w : boolean
|
||||
|
||||
interface Base {
|
||||
f(): this is Derived;
|
||||
>f : () => this is Derived
|
||||
}
|
||||
|
||||
interface Derived extends Base {
|
||||
x: number;
|
||||
>x : number
|
||||
}
|
||||
|
||||
declare const o6: Base | undefined;
|
||||
>o6 : Base | undefined
|
||||
|
||||
if (o6?.f()) {
|
||||
>o6?.f() : boolean | undefined
|
||||
>o6?.f : (() => this is Derived) | undefined
|
||||
>o6 : Base | undefined
|
||||
>f : (() => this is Derived) | undefined
|
||||
|
||||
o6; // Derived
|
||||
>o6 : Derived
|
||||
|
||||
o6.f;
|
||||
>o6.f : () => this is Derived
|
||||
>o6 : Derived
|
||||
>f : () => this is Derived
|
||||
}
|
||||
else {
|
||||
o6;
|
||||
>o6 : Base | undefined
|
||||
|
||||
o6?.f;
|
||||
>o6?.f : (() => this is Derived) | undefined
|
||||
>o6 : Base | undefined
|
||||
>f : (() => this is Derived) | undefined
|
||||
|
||||
o6.f;
|
||||
>o6.f : () => this is Derived
|
||||
>o6 : Base | undefined
|
||||
>f : () => this is Derived
|
||||
}
|
||||
o6;
|
||||
>o6 : Base | undefined
|
||||
|
||||
o6?.f;
|
||||
>o6?.f : (() => this is Derived) | undefined
|
||||
>o6 : Base | undefined
|
||||
>f : (() => this is Derived) | undefined
|
||||
|
||||
o6.f;
|
||||
>o6.f : () => this is Derived
|
||||
>o6 : Base | undefined
|
||||
>f : () => this is Derived
|
||||
|
||||
// asserts
|
||||
declare const isDefined: <T>(value: T) => asserts value is NonNullable<T>;
|
||||
>isDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>value : T
|
||||
|
||||
declare const isString: (value: unknown) => asserts value is string;
|
||||
>isString : (value: unknown) => asserts value is string
|
||||
>value : unknown
|
||||
|
||||
declare const maybeIsString: undefined | ((value: unknown) => asserts value is string);
|
||||
>maybeIsString : ((value: unknown) => asserts value is string) | undefined
|
||||
>value : unknown
|
||||
|
||||
declare const maybeNever: undefined | (() => never);
|
||||
>maybeNever : (() => never) | undefined
|
||||
|
||||
function f01(x: unknown) {
|
||||
>f01 : (x: unknown) => void
|
||||
>x : unknown
|
||||
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
isString?.(x);
|
||||
>isString?.(x) : void
|
||||
>isString : (value: unknown) => asserts value is string
|
||||
>x : unknown
|
||||
|
||||
x;
|
||||
>x : string
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
maybeIsString?.(x);
|
||||
>maybeIsString?.(x) : void | undefined
|
||||
>maybeIsString : ((value: unknown) => asserts value is string) | undefined
|
||||
>x : unknown
|
||||
|
||||
x;
|
||||
>x : unknown
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
isDefined(maybeIsString);
|
||||
>isDefined(maybeIsString) : void
|
||||
>isDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>maybeIsString : ((value: unknown) => asserts value is string) | undefined
|
||||
|
||||
maybeIsString?.(x);
|
||||
>maybeIsString?.(x) : void
|
||||
>maybeIsString : (value: unknown) => asserts value is string
|
||||
>x : unknown
|
||||
|
||||
x;
|
||||
>x : unknown
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
maybeNever?.();
|
||||
>maybeNever?.() : undefined
|
||||
>maybeNever : (() => never) | undefined
|
||||
|
||||
x;
|
||||
>x : unknown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//// [elementAccessChain.2.ts]
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.["b"];
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.["b"].c;
|
||||
o2?.b["c"];
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3["b"]?.c;
|
||||
o3.b?.["c"];
|
||||
|
||||
|
||||
//// [elementAccessChain.2.js]
|
||||
var _a, _b, _c, _d, _e;
|
||||
(_a = o1) === null || _a === void 0 ? void 0 : _a["b"];
|
||||
(_b = o2) === null || _b === void 0 ? void 0 : _b["b"].c;
|
||||
(_c = o2) === null || _c === void 0 ? void 0 : _c.b["c"];
|
||||
(_d = o3["b"]) === null || _d === void 0 ? void 0 : _d.c;
|
||||
(_e = o3.b) === null || _e === void 0 ? void 0 : _e["c"];
|
||||
@@ -0,0 +1,43 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.2.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : Symbol(o1, Decl(elementAccessChain.2.ts, 0, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.2.ts, 0, 31))
|
||||
|
||||
o1?.["b"];
|
||||
>o1 : Symbol(o1, Decl(elementAccessChain.2.ts, 0, 13))
|
||||
>"b" : Symbol(b, Decl(elementAccessChain.2.ts, 0, 31))
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : Symbol(o2, Decl(elementAccessChain.2.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.2.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(elementAccessChain.2.ts, 3, 36))
|
||||
|
||||
o2?.["b"].c;
|
||||
>o2?.["b"].c : Symbol(c, Decl(elementAccessChain.2.ts, 3, 36))
|
||||
>o2 : Symbol(o2, Decl(elementAccessChain.2.ts, 3, 13))
|
||||
>"b" : Symbol(b, Decl(elementAccessChain.2.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(elementAccessChain.2.ts, 3, 36))
|
||||
|
||||
o2?.b["c"];
|
||||
>o2?.b : Symbol(b, Decl(elementAccessChain.2.ts, 3, 31))
|
||||
>o2 : Symbol(o2, Decl(elementAccessChain.2.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.2.ts, 3, 31))
|
||||
>"c" : Symbol(c, Decl(elementAccessChain.2.ts, 3, 36))
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : Symbol(o3, Decl(elementAccessChain.2.ts, 7, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.2.ts, 7, 19))
|
||||
>c : Symbol(c, Decl(elementAccessChain.2.ts, 7, 36))
|
||||
|
||||
o3["b"]?.c;
|
||||
>o3["b"]?.c : Symbol(c, Decl(elementAccessChain.2.ts, 7, 36))
|
||||
>o3 : Symbol(o3, Decl(elementAccessChain.2.ts, 7, 13))
|
||||
>"b" : Symbol(b, Decl(elementAccessChain.2.ts, 7, 19))
|
||||
>c : Symbol(c, Decl(elementAccessChain.2.ts, 7, 36))
|
||||
|
||||
o3.b?.["c"];
|
||||
>o3.b : Symbol(b, Decl(elementAccessChain.2.ts, 7, 19))
|
||||
>o3 : Symbol(o3, Decl(elementAccessChain.2.ts, 7, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.2.ts, 7, 19))
|
||||
>"c" : Symbol(c, Decl(elementAccessChain.2.ts, 7, 36))
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.2.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : { b: string; }
|
||||
>b : string
|
||||
|
||||
o1?.["b"];
|
||||
>o1?.["b"] : string
|
||||
>o1 : { b: string; }
|
||||
>"b" : "b"
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
o2?.["b"].c;
|
||||
>o2?.["b"].c : string
|
||||
>o2?.["b"] : { c: string; }
|
||||
>o2 : { b: { c: string; }; }
|
||||
>"b" : "b"
|
||||
>c : string
|
||||
|
||||
o2?.b["c"];
|
||||
>o2?.b["c"] : string
|
||||
>o2?.b : { c: string; }
|
||||
>o2 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>"c" : "c"
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
o3["b"]?.c;
|
||||
>o3["b"]?.c : string
|
||||
>o3["b"] : { c: string; }
|
||||
>o3 : { b: { c: string; }; }
|
||||
>"b" : "b"
|
||||
>c : string
|
||||
|
||||
o3.b?.["c"];
|
||||
>o3.b?.["c"] : string
|
||||
>o3.b : { c: string; }
|
||||
>o3 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>"c" : "c"
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(3,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(4,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(5,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(6,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(8,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(9,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(10,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(11,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(13,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(14,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(15,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(16,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(18,6): error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(19,6): error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(20,6): error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(21,6): error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(23,7): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(24,7): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(25,7): error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(26,7): error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(27,5): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts(28,5): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts (22 errors) ====
|
||||
declare const obj: any;
|
||||
|
||||
obj?.["a"]++;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
obj?.a["b"]++;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
obj?.["a"]--;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
obj?.a["b"]--;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
|
||||
++obj?.["a"];
|
||||
~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
++obj?.a["b"];
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
--obj?.["a"];
|
||||
~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
--obj?.a["b"];
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
|
||||
obj?.["a"] = 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
obj?.a["b"] = 1;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
obj?.["a"] += 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
obj?.a["b"] += 1;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
|
||||
for (obj?.["a"] in {});
|
||||
~~~~~~~~~~
|
||||
!!! error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
for (obj?.a["b"] in {});
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
for (obj?.["a"] of []);
|
||||
~~~~~~~~~~
|
||||
!!! error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
for (obj?.a["b"] of []);
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
|
||||
({ a: obj?.["a"] } = { a: 1 });
|
||||
~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
({ a: obj?.a["b"] } = { a: 1 });
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
({ ...obj?.["a"] } = { a: 1 });
|
||||
~~~~~~~~~~
|
||||
!!! error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
({ ...obj?.a["b"] } = { a: 1 });
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
[...obj?.["a"]] = [];
|
||||
~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
[...obj?.a["b"]] = [];
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//// [elementAccessChain.3.ts]
|
||||
declare const obj: any;
|
||||
|
||||
obj?.["a"]++;
|
||||
obj?.a["b"]++;
|
||||
obj?.["a"]--;
|
||||
obj?.a["b"]--;
|
||||
|
||||
++obj?.["a"];
|
||||
++obj?.a["b"];
|
||||
--obj?.["a"];
|
||||
--obj?.a["b"];
|
||||
|
||||
obj?.["a"] = 1;
|
||||
obj?.a["b"] = 1;
|
||||
obj?.["a"] += 1;
|
||||
obj?.a["b"] += 1;
|
||||
|
||||
for (obj?.["a"] in {});
|
||||
for (obj?.a["b"] in {});
|
||||
for (obj?.["a"] of []);
|
||||
for (obj?.a["b"] of []);
|
||||
|
||||
({ a: obj?.["a"] } = { a: 1 });
|
||||
({ a: obj?.a["b"] } = { a: 1 });
|
||||
({ ...obj?.["a"] } = { a: 1 });
|
||||
({ ...obj?.a["b"] } = { a: 1 });
|
||||
[...obj?.["a"]] = [];
|
||||
[...obj?.a["b"]] = [];
|
||||
|
||||
|
||||
//// [elementAccessChain.3.js]
|
||||
"use strict";
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
||||
((_a = obj) === null || _a === void 0 ? void 0 : _a["a"])++;
|
||||
((_b = obj) === null || _b === void 0 ? void 0 : _b.a["b"])++;
|
||||
((_c = obj) === null || _c === void 0 ? void 0 : _c["a"])--;
|
||||
((_d = obj) === null || _d === void 0 ? void 0 : _d.a["b"])--;
|
||||
++((_e = obj) === null || _e === void 0 ? void 0 : _e["a"]);
|
||||
++((_f = obj) === null || _f === void 0 ? void 0 : _f.a["b"]);
|
||||
--((_g = obj) === null || _g === void 0 ? void 0 : _g["a"]);
|
||||
--((_h = obj) === null || _h === void 0 ? void 0 : _h.a["b"]);
|
||||
(_j = obj) === null || _j === void 0 ? void 0 : _j["a"] = 1;
|
||||
(_k = obj) === null || _k === void 0 ? void 0 : _k.a["b"] = 1;
|
||||
(_l = obj) === null || _l === void 0 ? void 0 : _l["a"] += 1;
|
||||
(_m = obj) === null || _m === void 0 ? void 0 : _m.a["b"] += 1;
|
||||
for ((_o = obj) === null || _o === void 0 ? void 0 : _o["a"] in {})
|
||||
;
|
||||
for ((_p = obj) === null || _p === void 0 ? void 0 : _p.a["b"] in {})
|
||||
;
|
||||
for (var _i = 0, _y = []; _i < _y.length; _i++) {
|
||||
(_q = obj) === null || _q === void 0 ? void 0 : _q["a"] = _y[_i];
|
||||
;
|
||||
}
|
||||
for (var _z = 0, _0 = []; _z < _0.length; _z++) {
|
||||
(_r = obj) === null || _r === void 0 ? void 0 : _r.a["b"] = _0[_z];
|
||||
;
|
||||
}
|
||||
((_s = obj) === null || _s === void 0 ? void 0 : _s["a"] = { a: 1 }.a);
|
||||
((_t = obj) === null || _t === void 0 ? void 0 : _t.a["b"] = { a: 1 }.a);
|
||||
((_u = obj) === null || _u === void 0 ? void 0 : _u["a"] = __rest({ a: 1 }, []));
|
||||
((_v = obj) === null || _v === void 0 ? void 0 : _v.a["b"] = __rest({ a: 1 }, []));
|
||||
(_w = obj) === null || _w === void 0 ? void 0 : _w["a"] = [].slice(0);
|
||||
(_x = obj) === null || _x === void 0 ? void 0 : _x.a["b"] = [].slice(0);
|
||||
@@ -0,0 +1,76 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts ===
|
||||
declare const obj: any;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.["a"]++;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a["b"]++;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.["a"]--;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a["b"]--;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
++obj?.["a"];
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
++obj?.a["b"];
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
--obj?.["a"];
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
--obj?.a["b"];
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.["a"] = 1;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a["b"] = 1;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.["a"] += 1;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a["b"] += 1;
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.["a"] in {});
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.a["b"] in {});
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.["a"] of []);
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.a["b"] of []);
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
({ a: obj?.["a"] } = { a: 1 });
|
||||
>a : Symbol(a, Decl(elementAccessChain.3.ts, 22, 2))
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(elementAccessChain.3.ts, 22, 22))
|
||||
|
||||
({ a: obj?.a["b"] } = { a: 1 });
|
||||
>a : Symbol(a, Decl(elementAccessChain.3.ts, 23, 2))
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(elementAccessChain.3.ts, 23, 23))
|
||||
|
||||
({ ...obj?.["a"] } = { a: 1 });
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(elementAccessChain.3.ts, 24, 22))
|
||||
|
||||
({ ...obj?.a["b"] } = { a: 1 });
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(elementAccessChain.3.ts, 25, 23))
|
||||
|
||||
[...obj?.["a"]] = [];
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
[...obj?.a["b"]] = [];
|
||||
>obj : Symbol(obj, Decl(elementAccessChain.3.ts, 0, 13))
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.3.ts ===
|
||||
declare const obj: any;
|
||||
>obj : any
|
||||
|
||||
obj?.["a"]++;
|
||||
>obj?.["a"]++ : number
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
|
||||
obj?.a["b"]++;
|
||||
>obj?.a["b"]++ : number
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
|
||||
obj?.["a"]--;
|
||||
>obj?.["a"]-- : number
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
|
||||
obj?.a["b"]--;
|
||||
>obj?.a["b"]-- : number
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
|
||||
++obj?.["a"];
|
||||
>++obj?.["a"] : number
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
|
||||
++obj?.a["b"];
|
||||
>++obj?.a["b"] : number
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
|
||||
--obj?.["a"];
|
||||
>--obj?.["a"] : number
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
|
||||
--obj?.a["b"];
|
||||
>--obj?.a["b"] : number
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
|
||||
obj?.["a"] = 1;
|
||||
>obj?.["a"] = 1 : 1
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>1 : 1
|
||||
|
||||
obj?.a["b"] = 1;
|
||||
>obj?.a["b"] = 1 : 1
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>1 : 1
|
||||
|
||||
obj?.["a"] += 1;
|
||||
>obj?.["a"] += 1 : any
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>1 : 1
|
||||
|
||||
obj?.a["b"] += 1;
|
||||
>obj?.a["b"] += 1 : any
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>1 : 1
|
||||
|
||||
for (obj?.["a"] in {});
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>{} : {}
|
||||
|
||||
for (obj?.a["b"] in {});
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>{} : {}
|
||||
|
||||
for (obj?.["a"] of []);
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>[] : never[]
|
||||
|
||||
for (obj?.a["b"] of []);
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>[] : never[]
|
||||
|
||||
({ a: obj?.["a"] } = { a: 1 });
|
||||
>({ a: obj?.["a"] } = { a: 1 }) : { a: number; }
|
||||
>{ a: obj?.["a"] } = { a: 1 } : { a: number; }
|
||||
>{ a: obj?.["a"] } : { a: any; }
|
||||
>a : any
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
({ a: obj?.a["b"] } = { a: 1 });
|
||||
>({ a: obj?.a["b"] } = { a: 1 }) : { a: number; }
|
||||
>{ a: obj?.a["b"] } = { a: 1 } : { a: number; }
|
||||
>{ a: obj?.a["b"] } : { a: any; }
|
||||
>a : any
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
({ ...obj?.["a"] } = { a: 1 });
|
||||
>({ ...obj?.["a"] } = { a: 1 }) : { a: number; }
|
||||
>{ ...obj?.["a"] } = { a: 1 } : { a: number; }
|
||||
>{ ...obj?.["a"] } : any
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
({ ...obj?.a["b"] } = { a: 1 });
|
||||
>({ ...obj?.a["b"] } = { a: 1 }) : { a: number; }
|
||||
>{ ...obj?.a["b"] } = { a: 1 } : { a: number; }
|
||||
>{ ...obj?.a["b"] } : any
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
[...obj?.["a"]] = [];
|
||||
>[...obj?.["a"]] = [] : never[]
|
||||
>[...obj?.["a"]] : never[]
|
||||
>...obj?.["a"] : any
|
||||
>obj?.["a"] : any
|
||||
>obj : any
|
||||
>"a" : "a"
|
||||
>[] : never[]
|
||||
|
||||
[...obj?.a["b"]] = [];
|
||||
>[...obj?.a["b"]] = [] : never[]
|
||||
>[...obj?.a["b"]] : never[]
|
||||
>...obj?.a["b"] : any
|
||||
>obj?.a["b"] : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>"b" : "b"
|
||||
>[] : never[]
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//// [elementAccessChain.ts]
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.["b"];
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.["b"].c;
|
||||
o2?.b["c"];
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3["b"]?.c;
|
||||
o3.b?.["c"];
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
o4.b?.["c"].d?.e;
|
||||
o4.b?.["c"].d?.["e"];
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
o5.b?.()["c"].d?.e;
|
||||
o5.b?.()["c"].d?.["e"];
|
||||
o5["b"]?.()["c"].d?.e;
|
||||
o5["b"]?.()["c"].d?.["e"];
|
||||
|
||||
|
||||
//// [elementAccessChain.js]
|
||||
"use strict";
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
||||
(_a = o1) === null || _a === void 0 ? void 0 : _a["b"];
|
||||
(_b = o2) === null || _b === void 0 ? void 0 : _b["b"].c;
|
||||
(_c = o2) === null || _c === void 0 ? void 0 : _c.b["c"];
|
||||
(_d = o3["b"]) === null || _d === void 0 ? void 0 : _d.c;
|
||||
(_e = o3.b) === null || _e === void 0 ? void 0 : _e["c"];
|
||||
(_g = (_f = o4.b) === null || _f === void 0 ? void 0 : _f["c"].d) === null || _g === void 0 ? void 0 : _g.e;
|
||||
(_j = (_h = o4.b) === null || _h === void 0 ? void 0 : _h["c"].d) === null || _j === void 0 ? void 0 : _j["e"];
|
||||
(_m = (_l = (_k = o5).b) === null || _l === void 0 ? void 0 : _l.call(_k)["c"].d) === null || _m === void 0 ? void 0 : _m.e;
|
||||
(_q = (_p = (_o = o5).b) === null || _p === void 0 ? void 0 : _p.call(_o)["c"].d) === null || _q === void 0 ? void 0 : _q["e"];
|
||||
(_t = (_s = (_r = o5)["b"]) === null || _s === void 0 ? void 0 : _s.call(_r)["c"].d) === null || _t === void 0 ? void 0 : _t.e;
|
||||
(_w = (_v = (_u = o5)["b"]) === null || _v === void 0 ? void 0 : _v.call(_u)["c"].d) === null || _w === void 0 ? void 0 : _w["e"];
|
||||
@@ -0,0 +1,99 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : Symbol(o1, Decl(elementAccessChain.ts, 0, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 0, 31))
|
||||
|
||||
o1?.["b"];
|
||||
>o1 : Symbol(o1, Decl(elementAccessChain.ts, 0, 13))
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : Symbol(o2, Decl(elementAccessChain.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(elementAccessChain.ts, 3, 36))
|
||||
|
||||
o2?.["b"].c;
|
||||
>o2?.["b"].c : Symbol(c, Decl(elementAccessChain.ts, 3, 36))
|
||||
>o2 : Symbol(o2, Decl(elementAccessChain.ts, 3, 13))
|
||||
>c : Symbol(c, Decl(elementAccessChain.ts, 3, 36))
|
||||
|
||||
o2?.b["c"];
|
||||
>o2?.b : Symbol(b, Decl(elementAccessChain.ts, 3, 31))
|
||||
>o2 : Symbol(o2, Decl(elementAccessChain.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 3, 31))
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : Symbol(o3, Decl(elementAccessChain.ts, 7, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 7, 19))
|
||||
>c : Symbol(c, Decl(elementAccessChain.ts, 7, 36))
|
||||
|
||||
o3["b"]?.c;
|
||||
>o3["b"]?.c : Symbol(c, Decl(elementAccessChain.ts, 7, 36))
|
||||
>o3 : Symbol(o3, Decl(elementAccessChain.ts, 7, 13))
|
||||
>"b" : Symbol(b, Decl(elementAccessChain.ts, 7, 19))
|
||||
>c : Symbol(c, Decl(elementAccessChain.ts, 7, 36))
|
||||
|
||||
o3.b?.["c"];
|
||||
>o3.b : Symbol(b, Decl(elementAccessChain.ts, 7, 19))
|
||||
>o3 : Symbol(o3, Decl(elementAccessChain.ts, 7, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 7, 19))
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
>o4 : Symbol(o4, Decl(elementAccessChain.ts, 11, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 11, 19))
|
||||
>c : Symbol(c, Decl(elementAccessChain.ts, 11, 25))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 11, 30))
|
||||
>e : Symbol(e, Decl(elementAccessChain.ts, 11, 36))
|
||||
|
||||
o4.b?.["c"].d?.e;
|
||||
>o4.b?.["c"].d?.e : Symbol(e, Decl(elementAccessChain.ts, 11, 36))
|
||||
>o4.b?.["c"].d : Symbol(d, Decl(elementAccessChain.ts, 11, 30))
|
||||
>o4.b : Symbol(b, Decl(elementAccessChain.ts, 11, 19))
|
||||
>o4 : Symbol(o4, Decl(elementAccessChain.ts, 11, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 11, 19))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 11, 30))
|
||||
>e : Symbol(e, Decl(elementAccessChain.ts, 11, 36))
|
||||
|
||||
o4.b?.["c"].d?.["e"];
|
||||
>o4.b?.["c"].d : Symbol(d, Decl(elementAccessChain.ts, 11, 30))
|
||||
>o4.b : Symbol(b, Decl(elementAccessChain.ts, 11, 19))
|
||||
>o4 : Symbol(o4, Decl(elementAccessChain.ts, 11, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 11, 19))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 11, 30))
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
>o5 : Symbol(o5, Decl(elementAccessChain.ts, 15, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>c : Symbol(c, Decl(elementAccessChain.ts, 15, 27))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>e : Symbol(e, Decl(elementAccessChain.ts, 15, 38))
|
||||
|
||||
o5.b?.()["c"].d?.e;
|
||||
>o5.b?.()["c"].d?.e : Symbol(e, Decl(elementAccessChain.ts, 15, 38))
|
||||
>o5.b?.()["c"].d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>o5.b : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>o5 : Symbol(o5, Decl(elementAccessChain.ts, 15, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>e : Symbol(e, Decl(elementAccessChain.ts, 15, 38))
|
||||
|
||||
o5.b?.()["c"].d?.["e"];
|
||||
>o5.b?.()["c"].d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>o5.b : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>o5 : Symbol(o5, Decl(elementAccessChain.ts, 15, 13))
|
||||
>b : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
|
||||
o5["b"]?.()["c"].d?.e;
|
||||
>o5["b"]?.()["c"].d?.e : Symbol(e, Decl(elementAccessChain.ts, 15, 38))
|
||||
>o5["b"]?.()["c"].d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>o5 : Symbol(o5, Decl(elementAccessChain.ts, 15, 13))
|
||||
>"b" : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>e : Symbol(e, Decl(elementAccessChain.ts, 15, 38))
|
||||
|
||||
o5["b"]?.()["c"].d?.["e"];
|
||||
>o5["b"]?.()["c"].d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
>o5 : Symbol(o5, Decl(elementAccessChain.ts, 15, 13))
|
||||
>"b" : Symbol(b, Decl(elementAccessChain.ts, 15, 19))
|
||||
>d : Symbol(d, Decl(elementAccessChain.ts, 15, 32))
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : { b: string; } | undefined
|
||||
>b : string
|
||||
|
||||
o1?.["b"];
|
||||
>o1?.["b"] : string | undefined
|
||||
>o1 : { b: string; } | undefined
|
||||
>"b" : "b"
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : { b: { c: string; }; } | undefined
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
o2?.["b"].c;
|
||||
>o2?.["b"].c : string | undefined
|
||||
>o2?.["b"] : { c: string; } | undefined
|
||||
>o2 : { b: { c: string; }; } | undefined
|
||||
>"b" : "b"
|
||||
>c : string | undefined
|
||||
|
||||
o2?.b["c"];
|
||||
>o2?.b["c"] : string | undefined
|
||||
>o2?.b : { c: string; } | undefined
|
||||
>o2 : { b: { c: string; }; } | undefined
|
||||
>b : { c: string; } | undefined
|
||||
>"c" : "c"
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : { b: { c: string; } | undefined; }
|
||||
>b : { c: string; } | undefined
|
||||
>c : string
|
||||
|
||||
o3["b"]?.c;
|
||||
>o3["b"]?.c : string | undefined
|
||||
>o3["b"] : { c: string; } | undefined
|
||||
>o3 : { b: { c: string; } | undefined; }
|
||||
>"b" : "b"
|
||||
>c : string | undefined
|
||||
|
||||
o3.b?.["c"];
|
||||
>o3.b?.["c"] : string | undefined
|
||||
>o3.b : { c: string; } | undefined
|
||||
>o3 : { b: { c: string; } | undefined; }
|
||||
>b : { c: string; } | undefined
|
||||
>"c" : "c"
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
>o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; }
|
||||
>b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>c : { d?: { e: string; } | undefined; }
|
||||
>d : { e: string; } | undefined
|
||||
>e : string
|
||||
|
||||
o4.b?.["c"].d?.e;
|
||||
>o4.b?.["c"].d?.e : string | undefined
|
||||
>o4.b?.["c"].d : { e: string; } | undefined
|
||||
>o4.b?.["c"] : { d?: { e: string; } | undefined; } | undefined
|
||||
>o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; }
|
||||
>b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>"c" : "c"
|
||||
>d : { e: string; } | undefined
|
||||
>e : string | undefined
|
||||
|
||||
o4.b?.["c"].d?.["e"];
|
||||
>o4.b?.["c"].d?.["e"] : string | undefined
|
||||
>o4.b?.["c"].d : { e: string; } | undefined
|
||||
>o4.b?.["c"] : { d?: { e: string; } | undefined; } | undefined
|
||||
>o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; }
|
||||
>b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>"c" : "c"
|
||||
>d : { e: string; } | undefined
|
||||
>"e" : "e"
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>c : { d?: { e: string; } | undefined; }
|
||||
>d : { e: string; } | undefined
|
||||
>e : string
|
||||
|
||||
o5.b?.()["c"].d?.e;
|
||||
>o5.b?.()["c"].d?.e : string | undefined
|
||||
>o5.b?.()["c"].d : { e: string; } | undefined
|
||||
>o5.b?.()["c"] : { d?: { e: string; } | undefined; } | undefined
|
||||
>o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>"c" : "c"
|
||||
>d : { e: string; } | undefined
|
||||
>e : string | undefined
|
||||
|
||||
o5.b?.()["c"].d?.["e"];
|
||||
>o5.b?.()["c"].d?.["e"] : string | undefined
|
||||
>o5.b?.()["c"].d : { e: string; } | undefined
|
||||
>o5.b?.()["c"] : { d?: { e: string; } | undefined; } | undefined
|
||||
>o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>"c" : "c"
|
||||
>d : { e: string; } | undefined
|
||||
>"e" : "e"
|
||||
|
||||
o5["b"]?.()["c"].d?.e;
|
||||
>o5["b"]?.()["c"].d?.e : string | undefined
|
||||
>o5["b"]?.()["c"].d : { e: string; } | undefined
|
||||
>o5["b"]?.()["c"] : { d?: { e: string; } | undefined; } | undefined
|
||||
>o5["b"]?.() : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o5["b"] : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>"b" : "b"
|
||||
>"c" : "c"
|
||||
>d : { e: string; } | undefined
|
||||
>e : string | undefined
|
||||
|
||||
o5["b"]?.()["c"].d?.["e"];
|
||||
>o5["b"]?.()["c"].d?.["e"] : string | undefined
|
||||
>o5["b"]?.()["c"].d : { e: string; } | undefined
|
||||
>o5["b"]?.()["c"] : { d?: { e: string; } | undefined; } | undefined
|
||||
>o5["b"]?.() : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o5["b"] : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>"b" : "b"
|
||||
>"c" : "c"
|
||||
>d : { e: string; } | undefined
|
||||
>"e" : "e"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//// [propertyAccessChain.2.ts]
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.b;
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.b.c;
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3.b?.c;
|
||||
|
||||
|
||||
//// [propertyAccessChain.2.js]
|
||||
var _a, _b, _c;
|
||||
(_a = o1) === null || _a === void 0 ? void 0 : _a.b;
|
||||
(_b = o2) === null || _b === void 0 ? void 0 : _b.b.c;
|
||||
(_c = o3.b) === null || _c === void 0 ? void 0 : _c.c;
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.2.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : Symbol(o1, Decl(propertyAccessChain.2.ts, 0, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.2.ts, 0, 31))
|
||||
|
||||
o1?.b;
|
||||
>o1?.b : Symbol(b, Decl(propertyAccessChain.2.ts, 0, 31))
|
||||
>o1 : Symbol(o1, Decl(propertyAccessChain.2.ts, 0, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.2.ts, 0, 31))
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : Symbol(o2, Decl(propertyAccessChain.2.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.2.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.2.ts, 3, 36))
|
||||
|
||||
o2?.b.c;
|
||||
>o2?.b.c : Symbol(c, Decl(propertyAccessChain.2.ts, 3, 36))
|
||||
>o2?.b : Symbol(b, Decl(propertyAccessChain.2.ts, 3, 31))
|
||||
>o2 : Symbol(o2, Decl(propertyAccessChain.2.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.2.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.2.ts, 3, 36))
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : Symbol(o3, Decl(propertyAccessChain.2.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.2.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.2.ts, 6, 36))
|
||||
|
||||
o3.b?.c;
|
||||
>o3.b?.c : Symbol(c, Decl(propertyAccessChain.2.ts, 6, 36))
|
||||
>o3.b : Symbol(b, Decl(propertyAccessChain.2.ts, 6, 19))
|
||||
>o3 : Symbol(o3, Decl(propertyAccessChain.2.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.2.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.2.ts, 6, 36))
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.2.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : { b: string; }
|
||||
>b : string
|
||||
|
||||
o1?.b;
|
||||
>o1?.b : string
|
||||
>o1 : { b: string; }
|
||||
>b : string
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
o2?.b.c;
|
||||
>o2?.b.c : string
|
||||
>o2?.b : { c: string; }
|
||||
>o2 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
o3.b?.c;
|
||||
>o3.b?.c : string
|
||||
>o3.b : { c: string; }
|
||||
>o3 : { b: { c: string; }; }
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(3,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(4,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(5,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(6,1): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(8,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(9,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(10,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(11,3): error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(13,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(14,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(15,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(16,1): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(18,6): error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(19,6): error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(20,6): error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(21,6): error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(23,7): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(24,7): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(25,7): error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(26,7): error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(27,5): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts(28,5): error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts (22 errors) ====
|
||||
declare const obj: any;
|
||||
|
||||
obj?.a++;
|
||||
~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
obj?.a.b++;
|
||||
~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
obj?.a--;
|
||||
~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
obj?.a.b--;
|
||||
~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
|
||||
++obj?.a;
|
||||
~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
++obj?.a.b;
|
||||
~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
--obj?.a;
|
||||
~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
--obj?.a.b;
|
||||
~~~~~~~~
|
||||
!!! error TS2777: The operand of an increment or decrement operator may not be an optional property access.
|
||||
|
||||
obj?.a = 1;
|
||||
~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
obj?.a.b = 1;
|
||||
~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
obj?.a += 1;
|
||||
~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
obj?.a.b += 1;
|
||||
~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
|
||||
for (obj?.a in {});
|
||||
~~~~~~
|
||||
!!! error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
for (obj?.a.b in {});
|
||||
~~~~~~~~
|
||||
!!! error TS2780: The left-hand side of a 'for...in' statement may not be an optional property access.
|
||||
for (obj?.a of []);
|
||||
~~~~~~
|
||||
!!! error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
for (obj?.a.b of []);
|
||||
~~~~~~~~
|
||||
!!! error TS2781: The left-hand side of a 'for...of' statement may not be an optional property access.
|
||||
|
||||
({ a: obj?.a } = { a: 1 });
|
||||
~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
({ a: obj?.a.b } = { a: 1 });
|
||||
~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
({ ...obj?.a } = { a: 1 });
|
||||
~~~~~~
|
||||
!!! error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
({ ...obj?.a.b } = { a: 1 });
|
||||
~~~~~~~~
|
||||
!!! error TS2778: The target of an object rest assignment may not be an optional property access.
|
||||
[...obj?.a] = [];
|
||||
~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
[...obj?.a.b] = [];
|
||||
~~~~~~~~
|
||||
!!! error TS2779: The left-hand side of an assignment expression may not be an optional property access.
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//// [propertyAccessChain.3.ts]
|
||||
declare const obj: any;
|
||||
|
||||
obj?.a++;
|
||||
obj?.a.b++;
|
||||
obj?.a--;
|
||||
obj?.a.b--;
|
||||
|
||||
++obj?.a;
|
||||
++obj?.a.b;
|
||||
--obj?.a;
|
||||
--obj?.a.b;
|
||||
|
||||
obj?.a = 1;
|
||||
obj?.a.b = 1;
|
||||
obj?.a += 1;
|
||||
obj?.a.b += 1;
|
||||
|
||||
for (obj?.a in {});
|
||||
for (obj?.a.b in {});
|
||||
for (obj?.a of []);
|
||||
for (obj?.a.b of []);
|
||||
|
||||
({ a: obj?.a } = { a: 1 });
|
||||
({ a: obj?.a.b } = { a: 1 });
|
||||
({ ...obj?.a } = { a: 1 });
|
||||
({ ...obj?.a.b } = { a: 1 });
|
||||
[...obj?.a] = [];
|
||||
[...obj?.a.b] = [];
|
||||
|
||||
|
||||
//// [propertyAccessChain.3.js]
|
||||
"use strict";
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
||||
((_a = obj) === null || _a === void 0 ? void 0 : _a.a)++;
|
||||
((_b = obj) === null || _b === void 0 ? void 0 : _b.a.b)++;
|
||||
((_c = obj) === null || _c === void 0 ? void 0 : _c.a)--;
|
||||
((_d = obj) === null || _d === void 0 ? void 0 : _d.a.b)--;
|
||||
++((_e = obj) === null || _e === void 0 ? void 0 : _e.a);
|
||||
++((_f = obj) === null || _f === void 0 ? void 0 : _f.a.b);
|
||||
--((_g = obj) === null || _g === void 0 ? void 0 : _g.a);
|
||||
--((_h = obj) === null || _h === void 0 ? void 0 : _h.a.b);
|
||||
(_j = obj) === null || _j === void 0 ? void 0 : _j.a = 1;
|
||||
(_k = obj) === null || _k === void 0 ? void 0 : _k.a.b = 1;
|
||||
(_l = obj) === null || _l === void 0 ? void 0 : _l.a += 1;
|
||||
(_m = obj) === null || _m === void 0 ? void 0 : _m.a.b += 1;
|
||||
for ((_o = obj) === null || _o === void 0 ? void 0 : _o.a in {})
|
||||
;
|
||||
for ((_p = obj) === null || _p === void 0 ? void 0 : _p.a.b in {})
|
||||
;
|
||||
for (var _i = 0, _y = []; _i < _y.length; _i++) {
|
||||
(_q = obj) === null || _q === void 0 ? void 0 : _q.a = _y[_i];
|
||||
;
|
||||
}
|
||||
for (var _z = 0, _0 = []; _z < _0.length; _z++) {
|
||||
(_r = obj) === null || _r === void 0 ? void 0 : _r.a.b = _0[_z];
|
||||
;
|
||||
}
|
||||
((_s = obj) === null || _s === void 0 ? void 0 : _s.a = { a: 1 }.a);
|
||||
((_t = obj) === null || _t === void 0 ? void 0 : _t.a.b = { a: 1 }.a);
|
||||
((_u = obj) === null || _u === void 0 ? void 0 : _u.a = __rest({ a: 1 }, []));
|
||||
((_v = obj) === null || _v === void 0 ? void 0 : _v.a.b = __rest({ a: 1 }, []));
|
||||
(_w = obj) === null || _w === void 0 ? void 0 : _w.a = [].slice(0);
|
||||
(_x = obj) === null || _x === void 0 ? void 0 : _x.a.b = [].slice(0);
|
||||
@@ -0,0 +1,76 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts ===
|
||||
declare const obj: any;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a++;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a.b++;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a--;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a.b--;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
++obj?.a;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
++obj?.a.b;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
--obj?.a;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
--obj?.a.b;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a = 1;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a.b = 1;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a += 1;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
obj?.a.b += 1;
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.a in {});
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.a.b in {});
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.a of []);
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
for (obj?.a.b of []);
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
({ a: obj?.a } = { a: 1 });
|
||||
>a : Symbol(a, Decl(propertyAccessChain.3.ts, 22, 2))
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(propertyAccessChain.3.ts, 22, 18))
|
||||
|
||||
({ a: obj?.a.b } = { a: 1 });
|
||||
>a : Symbol(a, Decl(propertyAccessChain.3.ts, 23, 2))
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(propertyAccessChain.3.ts, 23, 20))
|
||||
|
||||
({ ...obj?.a } = { a: 1 });
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(propertyAccessChain.3.ts, 24, 18))
|
||||
|
||||
({ ...obj?.a.b } = { a: 1 });
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(propertyAccessChain.3.ts, 25, 20))
|
||||
|
||||
[...obj?.a] = [];
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
[...obj?.a.b] = [];
|
||||
>obj : Symbol(obj, Decl(propertyAccessChain.3.ts, 0, 13))
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.3.ts ===
|
||||
declare const obj: any;
|
||||
>obj : any
|
||||
|
||||
obj?.a++;
|
||||
>obj?.a++ : number
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
|
||||
obj?.a.b++;
|
||||
>obj?.a.b++ : number
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
|
||||
obj?.a--;
|
||||
>obj?.a-- : number
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
|
||||
obj?.a.b--;
|
||||
>obj?.a.b-- : number
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
|
||||
++obj?.a;
|
||||
>++obj?.a : number
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
|
||||
++obj?.a.b;
|
||||
>++obj?.a.b : number
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
|
||||
--obj?.a;
|
||||
>--obj?.a : number
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
|
||||
--obj?.a.b;
|
||||
>--obj?.a.b : number
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
|
||||
obj?.a = 1;
|
||||
>obj?.a = 1 : 1
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
obj?.a.b = 1;
|
||||
>obj?.a.b = 1 : 1
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>1 : 1
|
||||
|
||||
obj?.a += 1;
|
||||
>obj?.a += 1 : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>1 : 1
|
||||
|
||||
obj?.a.b += 1;
|
||||
>obj?.a.b += 1 : any
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>1 : 1
|
||||
|
||||
for (obj?.a in {});
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>{} : {}
|
||||
|
||||
for (obj?.a.b in {});
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>{} : {}
|
||||
|
||||
for (obj?.a of []);
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>[] : never[]
|
||||
|
||||
for (obj?.a.b of []);
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>[] : never[]
|
||||
|
||||
({ a: obj?.a } = { a: 1 });
|
||||
>({ a: obj?.a } = { a: 1 }) : { a: number; }
|
||||
>{ a: obj?.a } = { a: 1 } : { a: number; }
|
||||
>{ a: obj?.a } : { a: any; }
|
||||
>a : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
({ a: obj?.a.b } = { a: 1 });
|
||||
>({ a: obj?.a.b } = { a: 1 }) : { a: number; }
|
||||
>{ a: obj?.a.b } = { a: 1 } : { a: number; }
|
||||
>{ a: obj?.a.b } : { a: any; }
|
||||
>a : any
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
({ ...obj?.a } = { a: 1 });
|
||||
>({ ...obj?.a } = { a: 1 }) : { a: number; }
|
||||
>{ ...obj?.a } = { a: 1 } : { a: number; }
|
||||
>{ ...obj?.a } : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
({ ...obj?.a.b } = { a: 1 });
|
||||
>({ ...obj?.a.b } = { a: 1 }) : { a: number; }
|
||||
>{ ...obj?.a.b } = { a: 1 } : { a: number; }
|
||||
>{ ...obj?.a.b } : any
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>{ a: 1 } : { a: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
|
||||
[...obj?.a] = [];
|
||||
>[...obj?.a] = [] : never[]
|
||||
>[...obj?.a] : never[]
|
||||
>...obj?.a : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>[] : never[]
|
||||
|
||||
[...obj?.a.b] = [];
|
||||
>[...obj?.a.b] = [] : never[]
|
||||
>[...obj?.a.b] : never[]
|
||||
>...obj?.a.b : any
|
||||
>obj?.a.b : any
|
||||
>obj?.a : any
|
||||
>obj : any
|
||||
>a : any
|
||||
>b : any
|
||||
>[] : never[]
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//// [propertyAccessChain.ts]
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.b;
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.b.c;
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3.b?.c;
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
o4.b?.c.d?.e;
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
o5.b?.().c.d?.e;
|
||||
|
||||
|
||||
//// [propertyAccessChain.js]
|
||||
"use strict";
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
||||
(_a = o1) === null || _a === void 0 ? void 0 : _a.b;
|
||||
(_b = o2) === null || _b === void 0 ? void 0 : _b.b.c;
|
||||
(_c = o3.b) === null || _c === void 0 ? void 0 : _c.c;
|
||||
(_e = (_d = o4.b) === null || _d === void 0 ? void 0 : _d.c.d) === null || _e === void 0 ? void 0 : _e.e;
|
||||
(_h = (_g = (_f = o5).b) === null || _g === void 0 ? void 0 : _g.call(_f).c.d) === null || _h === void 0 ? void 0 : _h.e;
|
||||
@@ -0,0 +1,70 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : Symbol(o1, Decl(propertyAccessChain.ts, 0, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 0, 31))
|
||||
|
||||
o1?.b;
|
||||
>o1?.b : Symbol(b, Decl(propertyAccessChain.ts, 0, 31))
|
||||
>o1 : Symbol(o1, Decl(propertyAccessChain.ts, 0, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 0, 31))
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : Symbol(o2, Decl(propertyAccessChain.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 3, 36))
|
||||
|
||||
o2?.b.c;
|
||||
>o2?.b.c : Symbol(c, Decl(propertyAccessChain.ts, 3, 36))
|
||||
>o2?.b : Symbol(b, Decl(propertyAccessChain.ts, 3, 31))
|
||||
>o2 : Symbol(o2, Decl(propertyAccessChain.ts, 3, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 3, 31))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 3, 36))
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : Symbol(o3, Decl(propertyAccessChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 6, 36))
|
||||
|
||||
o3.b?.c;
|
||||
>o3.b?.c : Symbol(c, Decl(propertyAccessChain.ts, 6, 36))
|
||||
>o3.b : Symbol(b, Decl(propertyAccessChain.ts, 6, 19))
|
||||
>o3 : Symbol(o3, Decl(propertyAccessChain.ts, 6, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 6, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 6, 36))
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
>o4 : Symbol(o4, Decl(propertyAccessChain.ts, 9, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 9, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 9, 25))
|
||||
>d : Symbol(d, Decl(propertyAccessChain.ts, 9, 30))
|
||||
>e : Symbol(e, Decl(propertyAccessChain.ts, 9, 36))
|
||||
|
||||
o4.b?.c.d?.e;
|
||||
>o4.b?.c.d?.e : Symbol(e, Decl(propertyAccessChain.ts, 9, 36))
|
||||
>o4.b?.c.d : Symbol(d, Decl(propertyAccessChain.ts, 9, 30))
|
||||
>o4.b?.c : Symbol(c, Decl(propertyAccessChain.ts, 9, 25))
|
||||
>o4.b : Symbol(b, Decl(propertyAccessChain.ts, 9, 19))
|
||||
>o4 : Symbol(o4, Decl(propertyAccessChain.ts, 9, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 9, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 9, 25))
|
||||
>d : Symbol(d, Decl(propertyAccessChain.ts, 9, 30))
|
||||
>e : Symbol(e, Decl(propertyAccessChain.ts, 9, 36))
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
>o5 : Symbol(o5, Decl(propertyAccessChain.ts, 12, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 12, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 12, 27))
|
||||
>d : Symbol(d, Decl(propertyAccessChain.ts, 12, 32))
|
||||
>e : Symbol(e, Decl(propertyAccessChain.ts, 12, 38))
|
||||
|
||||
o5.b?.().c.d?.e;
|
||||
>o5.b?.().c.d?.e : Symbol(e, Decl(propertyAccessChain.ts, 12, 38))
|
||||
>o5.b?.().c.d : Symbol(d, Decl(propertyAccessChain.ts, 12, 32))
|
||||
>o5.b?.().c : Symbol(c, Decl(propertyAccessChain.ts, 12, 27))
|
||||
>o5.b : Symbol(b, Decl(propertyAccessChain.ts, 12, 19))
|
||||
>o5 : Symbol(o5, Decl(propertyAccessChain.ts, 12, 13))
|
||||
>b : Symbol(b, Decl(propertyAccessChain.ts, 12, 19))
|
||||
>c : Symbol(c, Decl(propertyAccessChain.ts, 12, 27))
|
||||
>d : Symbol(d, Decl(propertyAccessChain.ts, 12, 32))
|
||||
>e : Symbol(e, Decl(propertyAccessChain.ts, 12, 38))
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.ts ===
|
||||
declare const o1: undefined | { b: string };
|
||||
>o1 : { b: string; } | undefined
|
||||
>b : string
|
||||
|
||||
o1?.b;
|
||||
>o1?.b : string | undefined
|
||||
>o1 : { b: string; } | undefined
|
||||
>b : string | undefined
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
>o2 : { b: { c: string; }; } | undefined
|
||||
>b : { c: string; }
|
||||
>c : string
|
||||
|
||||
o2?.b.c;
|
||||
>o2?.b.c : string | undefined
|
||||
>o2?.b : { c: string; } | undefined
|
||||
>o2 : { b: { c: string; }; } | undefined
|
||||
>b : { c: string; } | undefined
|
||||
>c : string | undefined
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
>o3 : { b: { c: string; } | undefined; }
|
||||
>b : { c: string; } | undefined
|
||||
>c : string
|
||||
|
||||
o3.b?.c;
|
||||
>o3.b?.c : string | undefined
|
||||
>o3.b : { c: string; } | undefined
|
||||
>o3 : { b: { c: string; } | undefined; }
|
||||
>b : { c: string; } | undefined
|
||||
>c : string | undefined
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
>o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; }
|
||||
>b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>c : { d?: { e: string; } | undefined; }
|
||||
>d : { e: string; } | undefined
|
||||
>e : string
|
||||
|
||||
o4.b?.c.d?.e;
|
||||
>o4.b?.c.d?.e : string | undefined
|
||||
>o4.b?.c.d : { e: string; } | undefined
|
||||
>o4.b?.c : { d?: { e: string; } | undefined; } | undefined
|
||||
>o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; }
|
||||
>b : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>c : { d?: { e: string; } | undefined; } | undefined
|
||||
>d : { e: string; } | undefined
|
||||
>e : string | undefined
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>c : { d?: { e: string; } | undefined; }
|
||||
>d : { e: string; } | undefined
|
||||
>e : string
|
||||
|
||||
o5.b?.().c.d?.e;
|
||||
>o5.b?.().c.d?.e : string | undefined
|
||||
>o5.b?.().c.d : { e: string; } | undefined
|
||||
>o5.b?.().c : { d?: { e: string; } | undefined; } | undefined
|
||||
>o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined
|
||||
>o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; }
|
||||
>b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined
|
||||
>c : { d?: { e: string; } | undefined; } | undefined
|
||||
>d : { e: string; } | undefined
|
||||
>e : string | undefined
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
tests/cases/conformance/expressions/optionalChaining/taggedTemplateChain/taggedTemplateChain.ts(2,4): error TS1358: Tagged template expressions are not permitted in an optional chain.
|
||||
tests/cases/conformance/expressions/optionalChaining/taggedTemplateChain/taggedTemplateChain.ts(4,4): error TS1358: Tagged template expressions are not permitted in an optional chain.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/optionalChaining/taggedTemplateChain/taggedTemplateChain.ts (2 errors) ====
|
||||
declare let a: any;
|
||||
a?.`b`;
|
||||
~~~
|
||||
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.
|
||||
|
||||
a?.`b${1}c`;
|
||||
~~~~~~~~
|
||||
!!! error TS1358: Tagged template expressions are not permitted in an optional chain.
|
||||
@@ -0,0 +1,13 @@
|
||||
//// [taggedTemplateChain.ts]
|
||||
declare let a: any;
|
||||
a?.`b`;
|
||||
|
||||
a?.`b${1}c`;
|
||||
|
||||
//// [taggedTemplateChain.js]
|
||||
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};
|
||||
a(__makeTemplateObject(["b"], ["b"]));
|
||||
a(__makeTemplateObject(["b", "c"], ["b", "c"]), 1);
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/taggedTemplateChain/taggedTemplateChain.ts ===
|
||||
declare let a: any;
|
||||
>a : Symbol(a, Decl(taggedTemplateChain.ts, 0, 11))
|
||||
|
||||
a?.`b`;
|
||||
>a : Symbol(a, Decl(taggedTemplateChain.ts, 0, 11))
|
||||
|
||||
a?.`b${1}c`;
|
||||
>a : Symbol(a, Decl(taggedTemplateChain.ts, 0, 11))
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/conformance/expressions/optionalChaining/taggedTemplateChain/taggedTemplateChain.ts ===
|
||||
declare let a: any;
|
||||
>a : any
|
||||
|
||||
a?.`b`;
|
||||
>a?.`b` : any
|
||||
>a : any
|
||||
>`b` : "b"
|
||||
|
||||
a?.`b${1}c`;
|
||||
>a?.`b${1}c` : any
|
||||
>a : any
|
||||
>`b${1}c` : string
|
||||
>1 : 1
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
// @strict: true
|
||||
// @allowUnreachableCode: false
|
||||
|
||||
// assignments in shortcutting chain
|
||||
declare const o: undefined | {
|
||||
[key: string]: any;
|
||||
[key: number]: any;
|
||||
(...args: any[]): any;
|
||||
};
|
||||
|
||||
let a: number;
|
||||
o?.[a = 1];
|
||||
a.toString();
|
||||
|
||||
let b: number;
|
||||
o?.x[b = 1];
|
||||
b.toString();
|
||||
|
||||
let c: number;
|
||||
o?.(c = 1)
|
||||
c.toString();
|
||||
|
||||
let d: number;
|
||||
o?.x(d = 1);
|
||||
d.toString();
|
||||
|
||||
// type predicates
|
||||
declare const f: undefined | ((x: any) => x is number);
|
||||
declare const x: string | number;
|
||||
if (f?.(x)) {
|
||||
x; // number
|
||||
f; // (x: any) => x is number
|
||||
f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
}
|
||||
x;
|
||||
f;
|
||||
f(x);
|
||||
|
||||
declare const o2: { f(x: any): x is number; } | undefined;
|
||||
if (o2?.f(x)) {
|
||||
x; // number
|
||||
o2.f; // (x: any) => x is number
|
||||
o2?.f;
|
||||
o2?.f(x);
|
||||
}
|
||||
else {
|
||||
x;
|
||||
o2;
|
||||
o2?.f;
|
||||
o2.f;
|
||||
}
|
||||
x;
|
||||
o2;
|
||||
o2?.f;
|
||||
o2.f;
|
||||
|
||||
declare const o3: { x: 1, y: string } | { x: 2, y: number } | undefined;
|
||||
if (o3?.x === 1) {
|
||||
o3; // TODO: should be `{ x: y, y: string }`
|
||||
o3.x; // TODO: should not be an error.
|
||||
o3?.x;
|
||||
}
|
||||
else {
|
||||
o3;
|
||||
o3?.x;
|
||||
o3.x;
|
||||
}
|
||||
o3;
|
||||
o3?.x;
|
||||
o3.x;
|
||||
|
||||
declare const o4: { x?: { y: boolean } };
|
||||
if (o4.x?.y) {
|
||||
o4.x; // { y: boolean }
|
||||
o4.x.y; // true
|
||||
o4.x?.y; // true
|
||||
}
|
||||
else {
|
||||
o4.x;
|
||||
o4.x?.y;
|
||||
o4.x.y;
|
||||
}
|
||||
o4.x;
|
||||
o4.x?.y;
|
||||
o4.x.y;
|
||||
|
||||
declare const o5: { x?: { y: { z?: { w: boolean } } } };
|
||||
if (o5.x?.y.z?.w) {
|
||||
o5.x;
|
||||
o5.x.y;
|
||||
o5.x.y.z;
|
||||
o5.x.y.z.w; // true
|
||||
o5.x.y.z?.w; // true
|
||||
o5.x?.y.z.w; // true
|
||||
o5.x?.y.z?.w; // true
|
||||
}
|
||||
else {
|
||||
o5.x;
|
||||
o5.x?.y;
|
||||
o5.x?.y.z;
|
||||
o5.x?.y.z?.w;
|
||||
o5.x.y;
|
||||
o5.x.y.z.w;
|
||||
}
|
||||
o5.x;
|
||||
o5.x?.y;
|
||||
o5.x?.y.z;
|
||||
o5.x?.y.z?.w;
|
||||
o5.x.y;
|
||||
o5.x.y.z.w;
|
||||
|
||||
interface Base {
|
||||
f(): this is Derived;
|
||||
}
|
||||
|
||||
interface Derived extends Base {
|
||||
x: number;
|
||||
}
|
||||
|
||||
declare const o6: Base | undefined;
|
||||
if (o6?.f()) {
|
||||
o6; // Derived
|
||||
o6.f;
|
||||
}
|
||||
else {
|
||||
o6;
|
||||
o6?.f;
|
||||
o6.f;
|
||||
}
|
||||
o6;
|
||||
o6?.f;
|
||||
o6.f;
|
||||
|
||||
// asserts
|
||||
declare const isDefined: <T>(value: T) => asserts value is NonNullable<T>;
|
||||
declare const isString: (value: unknown) => asserts value is string;
|
||||
declare const maybeIsString: undefined | ((value: unknown) => asserts value is string);
|
||||
declare const maybeNever: undefined | (() => never);
|
||||
|
||||
function f01(x: unknown) {
|
||||
if (!!true) {
|
||||
isString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
maybeIsString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
isDefined(maybeIsString);
|
||||
maybeIsString?.(x);
|
||||
x;
|
||||
}
|
||||
if (!!true) {
|
||||
maybeNever?.();
|
||||
x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// @strict: false
|
||||
|
||||
declare const o1: undefined | (() => number);
|
||||
o1?.();
|
||||
|
||||
declare const o2: undefined | { b: () => number };
|
||||
o2?.b();
|
||||
|
||||
declare const o3: { b: (() => { c: string }) | undefined };
|
||||
o3.b?.().c;
|
||||
@@ -0,0 +1,12 @@
|
||||
// @strict: true
|
||||
|
||||
declare function absorb<T>(): T;
|
||||
declare const a: { m?<T>(obj: {x: T}): T } | undefined;
|
||||
const n1: number = a?.m?.({x: 12 }); // should be an error (`undefined` is not assignable to `number`)
|
||||
const n2: number = a?.m?.({x: absorb()}); // likewise
|
||||
const n3: number | undefined = a?.m?.({x: 12}); // should be ok
|
||||
const n4: number | undefined = a?.m?.({x: absorb()}); // likewise
|
||||
|
||||
// Also a test showing `!` vs `?` for good measure
|
||||
let t1 = a?.m?.({x: 12});
|
||||
t1 = a!.m!({x: 12});
|
||||
@@ -0,0 +1,35 @@
|
||||
// @strict: true
|
||||
|
||||
declare const o1: undefined | ((...args: any[]) => number);
|
||||
o1?.();
|
||||
o1?.(1);
|
||||
o1?.(...[1, 2]);
|
||||
o1?.(1, ...[2, 3], 4);
|
||||
|
||||
declare const o2: undefined | { b: (...args: any[]) => number };
|
||||
o2?.b();
|
||||
o2?.b(1);
|
||||
o2?.b(...[1, 2]);
|
||||
o2?.b(1, ...[2, 3], 4);
|
||||
o2?.["b"]();
|
||||
o2?.["b"](1);
|
||||
o2?.["b"](...[1, 2]);
|
||||
o2?.["b"](1, ...[2, 3], 4);
|
||||
|
||||
declare const o3: { b: ((...args: any[]) => { c: string }) | undefined };
|
||||
o3.b?.().c;
|
||||
o3.b?.(1).c;
|
||||
o3.b?.(...[1, 2]).c;
|
||||
o3.b?.(1, ...[2, 3], 4).c;
|
||||
o3.b?.()["c"];
|
||||
o3.b?.(1)["c"];
|
||||
o3.b?.(...[1, 2])["c"];
|
||||
o3.b?.(1, ...[2, 3], 4)["c"];
|
||||
o3["b"]?.().c;
|
||||
o3["b"]?.(1).c;
|
||||
o3["b"]?.(...[1, 2]).c;
|
||||
o3["b"]?.(1, ...[2, 3], 4).c;
|
||||
|
||||
declare const o4: undefined | (<T>(f: (a: T) => T) => T);
|
||||
declare function incr(x: number): number;
|
||||
const v: number | undefined = o4?.(incr);
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// @strict: false
|
||||
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.["b"];
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.["b"].c;
|
||||
o2?.b["c"];
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3["b"]?.c;
|
||||
o3.b?.["c"];
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// @strict: true
|
||||
|
||||
declare const obj: any;
|
||||
|
||||
obj?.["a"]++;
|
||||
obj?.a["b"]++;
|
||||
obj?.["a"]--;
|
||||
obj?.a["b"]--;
|
||||
|
||||
++obj?.["a"];
|
||||
++obj?.a["b"];
|
||||
--obj?.["a"];
|
||||
--obj?.a["b"];
|
||||
|
||||
obj?.["a"] = 1;
|
||||
obj?.a["b"] = 1;
|
||||
obj?.["a"] += 1;
|
||||
obj?.a["b"] += 1;
|
||||
|
||||
for (obj?.["a"] in {});
|
||||
for (obj?.a["b"] in {});
|
||||
for (obj?.["a"] of []);
|
||||
for (obj?.a["b"] of []);
|
||||
|
||||
({ a: obj?.["a"] } = { a: 1 });
|
||||
({ a: obj?.a["b"] } = { a: 1 });
|
||||
({ ...obj?.["a"] } = { a: 1 });
|
||||
({ ...obj?.a["b"] } = { a: 1 });
|
||||
[...obj?.["a"]] = [];
|
||||
[...obj?.a["b"]] = [];
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// @strict: true
|
||||
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.["b"];
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.["b"].c;
|
||||
o2?.b["c"];
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3["b"]?.c;
|
||||
o3.b?.["c"];
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
o4.b?.["c"].d?.e;
|
||||
o4.b?.["c"].d?.["e"];
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
o5.b?.()["c"].d?.e;
|
||||
o5.b?.()["c"].d?.["e"];
|
||||
o5["b"]?.()["c"].d?.e;
|
||||
o5["b"]?.()["c"].d?.["e"];
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// @strict: false
|
||||
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.b;
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.b.c;
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3.b?.c;
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// @strict: true
|
||||
|
||||
declare const obj: any;
|
||||
|
||||
obj?.a++;
|
||||
obj?.a.b++;
|
||||
obj?.a--;
|
||||
obj?.a.b--;
|
||||
|
||||
++obj?.a;
|
||||
++obj?.a.b;
|
||||
--obj?.a;
|
||||
--obj?.a.b;
|
||||
|
||||
obj?.a = 1;
|
||||
obj?.a.b = 1;
|
||||
obj?.a += 1;
|
||||
obj?.a.b += 1;
|
||||
|
||||
for (obj?.a in {});
|
||||
for (obj?.a.b in {});
|
||||
for (obj?.a of []);
|
||||
for (obj?.a.b of []);
|
||||
|
||||
({ a: obj?.a } = { a: 1 });
|
||||
({ a: obj?.a.b } = { a: 1 });
|
||||
({ ...obj?.a } = { a: 1 });
|
||||
({ ...obj?.a.b } = { a: 1 });
|
||||
[...obj?.a] = [];
|
||||
[...obj?.a.b] = [];
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// @strict: true
|
||||
|
||||
declare const o1: undefined | { b: string };
|
||||
o1?.b;
|
||||
|
||||
declare const o2: undefined | { b: { c: string } };
|
||||
o2?.b.c;
|
||||
|
||||
declare const o3: { b: undefined | { c: string } };
|
||||
o3.b?.c;
|
||||
|
||||
declare const o4: { b?: { c: { d?: { e: string } } } };
|
||||
o4.b?.c.d?.e;
|
||||
|
||||
declare const o5: { b?(): { c: { d?: { e: string } } } };
|
||||
o5.b?.().c.d?.e;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
declare let a: any;
|
||||
a?.`b`;
|
||||
|
||||
a?.`b${1}c`;
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
// @strict: true
|
||||
|
||||
//// interface User {
|
||||
//// address?: {
|
||||
//// city: string;
|
||||
//// "postal code": string;
|
||||
//// }
|
||||
//// };
|
||||
//// declare const user: User;
|
||||
//// user.address[|?./**/|]
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: [
|
||||
{ name: "city", text: "(property) city: string" },
|
||||
{ name: "postal code", text: "(property) \"postal code\": string", insertText: "?.[\"postal code\"]", replacementSpan: test.ranges()[0] }
|
||||
],
|
||||
preferences: { includeInsertTextCompletions: true },
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
// @strict: true
|
||||
|
||||
//// interface User {
|
||||
//// address?: {
|
||||
//// city: string;
|
||||
//// "postal code": string;
|
||||
//// }
|
||||
//// };
|
||||
//// declare const user: User;
|
||||
//// user.address[|./**/|]
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: [
|
||||
{ name: "city", text: "(property) city: string", insertText: "?.city", replacementSpan: test.ranges()[0] },
|
||||
{ name: "postal code", text: "(property) \"postal code\": string", insertText: "?.[\"postal code\"]", replacementSpan: test.ranges()[0] }
|
||||
],
|
||||
preferences: { includeInsertTextCompletions: true },
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
// @strict: true
|
||||
|
||||
//// class Address {
|
||||
//// city: string = "";
|
||||
//// "postal code": string = "";
|
||||
//// method() {
|
||||
//// this[|./**/|]
|
||||
//// }
|
||||
//// }
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: [
|
||||
{ name: "city", text: "(property) Address.city: string", insertText: undefined },
|
||||
{ name: "postal code", text: "(property) Address[\"postal code\"]: string", insertText: "[\"postal code\"]", replacementSpan: test.ranges()[0] },
|
||||
{ name: "method" }
|
||||
],
|
||||
preferences: { includeInsertTextCompletions: true },
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
// @strict: true
|
||||
|
||||
//// interface Address {
|
||||
//// city: string = "";
|
||||
//// "postal code": string = "";
|
||||
//// }
|
||||
//// function f<T extends Address>(x: T) {
|
||||
//// x[|./**/|]
|
||||
//// }
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: [
|
||||
{ name: "city", text: "(property) Address.city: string" },
|
||||
{ name: "postal code", text: "(property) Address[\"postal code\"]: string", insertText: "[\"postal code\"]", replacementSpan: test.ranges()[0] }
|
||||
],
|
||||
preferences: { includeInsertTextCompletions: true },
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////function fnTest(str: string, num: number) { }
|
||||
////fnTest?.(/*1*/);
|
||||
|
||||
verify.signatureHelp(
|
||||
{
|
||||
marker: "1",
|
||||
text: 'fnTest(str: string, num: number): void',
|
||||
parameterCount: 2,
|
||||
parameterName: "str",
|
||||
parameterSpan: "str: string",
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////declare const fnTest: undefined | ((str: string, num: number) => void);
|
||||
////fnTest?.(/*1*/);
|
||||
|
||||
verify.signatureHelp(
|
||||
{
|
||||
marker: "1",
|
||||
text: 'fnTest(str: string, num: number): void',
|
||||
parameterCount: 2,
|
||||
parameterName: "str",
|
||||
parameterSpan: "str: string",
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user