mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #32695 from microsoft/assertionsInControlFlow
Assertions in control flow analysis
This commit is contained in:
+39
-15
@@ -564,7 +564,7 @@ namespace ts {
|
||||
if (!isIIFE) {
|
||||
currentFlow = { flags: FlowFlags.Start };
|
||||
if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) {
|
||||
currentFlow.container = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
|
||||
currentFlow.node = <FunctionExpression | ArrowFunction | MethodDeclaration>node;
|
||||
}
|
||||
}
|
||||
// We create a return control flow graph for IIFEs and constructors. For constructors
|
||||
@@ -581,6 +581,7 @@ namespace ts {
|
||||
if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((<FunctionLikeDeclaration>node).body)) {
|
||||
node.flags |= NodeFlags.HasImplicitReturn;
|
||||
if (hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn;
|
||||
(<FunctionLikeDeclaration>node).endFlowNode = currentFlow;
|
||||
}
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
node.flags |= emitFlags;
|
||||
@@ -671,6 +672,9 @@ namespace ts {
|
||||
bindJSDoc(node);
|
||||
return;
|
||||
}
|
||||
if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement && !options.allowUnreachableCode) {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.WhileStatement:
|
||||
bindWhileStatement(<WhileStatement>node);
|
||||
@@ -708,6 +712,9 @@ namespace ts {
|
||||
case SyntaxKind.CaseClause:
|
||||
bindCaseClause(<CaseClause>node);
|
||||
break;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
bindExpressionStatement(<ExpressionStatement>node);
|
||||
break;
|
||||
case SyntaxKind.LabeledStatement:
|
||||
bindLabeledStatement(<LabeledStatement>node);
|
||||
break;
|
||||
@@ -845,17 +852,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createBranchLabel(): FlowLabel {
|
||||
return {
|
||||
flags: FlowFlags.BranchLabel,
|
||||
antecedents: undefined
|
||||
};
|
||||
return { flags: FlowFlags.BranchLabel, antecedents: undefined };
|
||||
}
|
||||
|
||||
function createLoopLabel(): FlowLabel {
|
||||
return {
|
||||
flags: FlowFlags.LoopLabel,
|
||||
antecedents: undefined
|
||||
};
|
||||
return { flags: FlowFlags.LoopLabel, antecedents: undefined };
|
||||
}
|
||||
|
||||
function setFlowNodeReferenced(flow: FlowNode) {
|
||||
@@ -885,7 +886,7 @@ namespace ts {
|
||||
return antecedent;
|
||||
}
|
||||
setFlowNodeReferenced(antecedent);
|
||||
return flowNodeCreated({ flags, expression, antecedent });
|
||||
return flowNodeCreated({ flags, antecedent, node: expression });
|
||||
}
|
||||
|
||||
function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode {
|
||||
@@ -893,7 +894,7 @@ namespace ts {
|
||||
return antecedent;
|
||||
}
|
||||
setFlowNodeReferenced(antecedent);
|
||||
return flowNodeCreated({ flags: FlowFlags.SwitchClause, switchStatement, clauseStart, clauseEnd, antecedent });
|
||||
return flowNodeCreated({ flags: FlowFlags.SwitchClause, antecedent, switchStatement, clauseStart, clauseEnd });
|
||||
}
|
||||
|
||||
function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode {
|
||||
@@ -901,10 +902,14 @@ namespace ts {
|
||||
return flowNodeCreated({ flags: FlowFlags.Assignment, antecedent, node });
|
||||
}
|
||||
|
||||
function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode {
|
||||
setFlowNodeReferenced(antecedent);
|
||||
return flowNodeCreated({ flags: FlowFlags.Call, antecedent, node });
|
||||
}
|
||||
|
||||
function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode {
|
||||
setFlowNodeReferenced(antecedent);
|
||||
const res: FlowArrayMutation = flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node });
|
||||
return res;
|
||||
return flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node });
|
||||
}
|
||||
|
||||
function finishFlowLabel(flow: FlowLabel): FlowNode {
|
||||
@@ -1030,12 +1035,12 @@ namespace ts {
|
||||
function bindForInOrForOfStatement(node: ForInOrOfStatement): void {
|
||||
const preLoopLabel = createLoopLabel();
|
||||
const postLoopLabel = createBranchLabel();
|
||||
bind(node.expression);
|
||||
addAntecedent(preLoopLabel, currentFlow);
|
||||
currentFlow = preLoopLabel;
|
||||
if (node.kind === SyntaxKind.ForOfStatement) {
|
||||
bind(node.awaitModifier);
|
||||
}
|
||||
bind(node.expression);
|
||||
addAntecedent(postLoopLabel, currentFlow);
|
||||
bind(node.initializer);
|
||||
if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) {
|
||||
@@ -1222,7 +1227,8 @@ namespace ts {
|
||||
addAntecedent(postSwitchLabel, currentFlow);
|
||||
const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause);
|
||||
// We mark a switch statement as possibly exhaustive if it has no default clause and if all
|
||||
// case clauses have unreachable end points (e.g. they all return).
|
||||
// case clauses have unreachable end points (e.g. they all return). Note, we no longer need
|
||||
// this property in control flow analysis, it's there only for backwards compatibility.
|
||||
node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
|
||||
if (!hasDefault) {
|
||||
addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
|
||||
@@ -1281,6 +1287,24 @@ namespace ts {
|
||||
activeLabels!.pop();
|
||||
}
|
||||
|
||||
function isDottedName(node: Expression): boolean {
|
||||
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword ||
|
||||
node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression) ||
|
||||
node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((<ParenthesizedExpression>node).expression);
|
||||
}
|
||||
|
||||
function bindExpressionStatement(node: ExpressionStatement): void {
|
||||
bind(node.expression);
|
||||
// A top level call expression with a dotted function name and at least one argument
|
||||
// is potentially an assertion and is therefore included in the control flow.
|
||||
if (node.expression.kind === SyntaxKind.CallExpression) {
|
||||
const call = <CallExpression>node.expression;
|
||||
if (isDottedName(call.expression)) {
|
||||
currentFlow = createFlowCall(currentFlow, call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bindLabeledStatement(node: LabeledStatement): void {
|
||||
const preStatementLabel = createLoopLabel();
|
||||
const postStatementLabel = createBranchLabel();
|
||||
|
||||
+246
-111
@@ -672,6 +672,7 @@ namespace ts {
|
||||
const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType);
|
||||
const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
|
||||
const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
|
||||
const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
|
||||
@@ -702,7 +703,7 @@ namespace ts {
|
||||
markerSubType.constraint = markerSuperType;
|
||||
const markerOtherType = createTypeParameter();
|
||||
|
||||
const noTypePredicate = createIdentifierTypePredicate("<<unresolved>>", 0, anyType);
|
||||
const noTypePredicate = createTypePredicate(TypePredicateKind.Identifier, "<<unresolved>>", 0, anyType);
|
||||
|
||||
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
@@ -821,6 +822,8 @@ namespace ts {
|
||||
let sharedFlowCount = 0;
|
||||
let flowAnalysisDisabled = false;
|
||||
let flowInvocationCount = 0;
|
||||
let lastFlowNode: FlowNode | undefined;
|
||||
let lastFlowNodeReachable: boolean;
|
||||
|
||||
const emptyStringType = getLiteralType("");
|
||||
const zeroType = getLiteralType(0);
|
||||
@@ -842,6 +845,7 @@ namespace ts {
|
||||
const flowLoopTypes: Type[][] = [];
|
||||
const sharedFlowNodes: FlowNode[] = [];
|
||||
const sharedFlowTypes: FlowType[] = [];
|
||||
const flowNodeReachable: (boolean | undefined)[] = [];
|
||||
const potentialThisCollisions: Node[] = [];
|
||||
const potentialNewTargetCollisions: Node[] = [];
|
||||
const awaitedTypeStack: number[] = [];
|
||||
@@ -4247,11 +4251,14 @@ namespace ts {
|
||||
let returnTypeNode: TypeNode | undefined;
|
||||
const typePredicate = getTypePredicateOfSignature(signature);
|
||||
if (typePredicate) {
|
||||
const parameterName = typePredicate.kind === TypePredicateKind.Identifier ?
|
||||
const assertsModifier = typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ?
|
||||
createToken(SyntaxKind.AssertsKeyword) :
|
||||
undefined;
|
||||
const parameterName = typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ?
|
||||
setEmitFlags(createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) :
|
||||
createThisTypeNode();
|
||||
const typeNode = typeToTypeNodeHelper(typePredicate.type, context);
|
||||
returnTypeNode = createTypePredicateNode(parameterName, typeNode);
|
||||
const typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context);
|
||||
returnTypeNode = createTypePredicateNodeWithModifier(assertsModifier, parameterName, typeNode);
|
||||
}
|
||||
else {
|
||||
const returnType = getReturnTypeOfSignature(signature);
|
||||
@@ -4718,9 +4725,10 @@ namespace ts {
|
||||
return writer ? typePredicateToStringWorker(writer).getText() : usingSingleLineStringWriter(typePredicateToStringWorker);
|
||||
|
||||
function typePredicateToStringWorker(writer: EmitTextWriter) {
|
||||
const predicate = createTypePredicateNode(
|
||||
typePredicate.kind === TypePredicateKind.Identifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(),
|
||||
nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)!, // TODO: GH#18217
|
||||
const predicate = createTypePredicateNodeWithModifier(
|
||||
typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createToken(SyntaxKind.AssertsKeyword) : undefined,
|
||||
typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(),
|
||||
typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217
|
||||
);
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration);
|
||||
@@ -8497,12 +8505,8 @@ namespace ts {
|
||||
return isBracketed || !!typeExpression && typeExpression.type.kind === SyntaxKind.JSDocOptionalType;
|
||||
}
|
||||
|
||||
function createIdentifierTypePredicate(parameterName: string, parameterIndex: number, type: Type): IdentifierTypePredicate {
|
||||
return { kind: TypePredicateKind.Identifier, parameterName, parameterIndex, type };
|
||||
}
|
||||
|
||||
function createThisTypePredicate(type: Type): ThisTypePredicate {
|
||||
return { kind: TypePredicateKind.This, type };
|
||||
function createTypePredicate(kind: TypePredicateKind, parameterName: string | undefined, parameterIndex: number | undefined, type: Type | undefined): TypePredicate {
|
||||
return { kind, parameterName, parameterIndex, type } as TypePredicate;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8737,10 +8741,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function signatureHasTypePredicate(signature: Signature): boolean {
|
||||
return getTypePredicateOfSignature(signature) !== undefined;
|
||||
}
|
||||
|
||||
function getTypePredicateOfSignature(signature: Signature): TypePredicate | undefined {
|
||||
if (!signature.resolvedTypePredicate) {
|
||||
if (signature.target) {
|
||||
@@ -8768,18 +8768,13 @@ namespace ts {
|
||||
return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
|
||||
}
|
||||
|
||||
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, signature: Signature): IdentifierTypePredicate | ThisTypePredicate {
|
||||
const { parameterName } = node;
|
||||
const type = getTypeFromTypeNode(node.type);
|
||||
if (parameterName.kind === SyntaxKind.Identifier) {
|
||||
return createIdentifierTypePredicate(
|
||||
parameterName.escapedText as string,
|
||||
findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText),
|
||||
type);
|
||||
}
|
||||
else {
|
||||
return createThisTypePredicate(type);
|
||||
}
|
||||
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, signature: Signature): TypePredicate {
|
||||
const parameterName = node.parameterName;
|
||||
const type = node.type && getTypeFromTypeNode(node.type);
|
||||
return parameterName.kind === SyntaxKind.ThisType ?
|
||||
createTypePredicate(node.assertsModifier ? TypePredicateKind.AssertsThis : TypePredicateKind.This, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) :
|
||||
createTypePredicate(node.assertsModifier ? TypePredicateKind.AssertsIdentifier : TypePredicateKind.Identifier, parameterName.escapedText as string,
|
||||
findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText), type);
|
||||
}
|
||||
|
||||
function getReturnTypeOfSignature(signature: Signature): Type {
|
||||
@@ -9868,7 +9863,7 @@ namespace ts {
|
||||
const types: Type[] = [];
|
||||
for (const sig of signatures) {
|
||||
const pred = getTypePredicateOfSignature(sig);
|
||||
if (!pred) {
|
||||
if (!pred || pred.kind === TypePredicateKind.AssertsThis || pred.kind === TypePredicateKind.AssertsIdentifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -9888,15 +9883,11 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
const unionType = getUnionType(types);
|
||||
return isIdentifierTypePredicate(first)
|
||||
? createIdentifierTypePredicate(first.parameterName, first.parameterIndex, unionType)
|
||||
: createThisTypePredicate(unionType);
|
||||
return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, unionType);
|
||||
}
|
||||
|
||||
function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean {
|
||||
return isIdentifierTypePredicate(a)
|
||||
? isIdentifierTypePredicate(b) && a.parameterIndex === b.parameterIndex
|
||||
: !isIdentifierTypePredicate(b);
|
||||
return a.kind === b.kind && a.parameterIndex === b.parameterIndex;
|
||||
}
|
||||
|
||||
// This function assumes the constituent type list is sorted and deduplicated.
|
||||
@@ -11196,7 +11187,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeReference:
|
||||
return getTypeFromTypeReference(<TypeReferenceNode>node);
|
||||
case SyntaxKind.TypePredicate:
|
||||
return booleanType;
|
||||
return (<TypePredicateNode>node).assertsModifier ? voidType : booleanType;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return getTypeFromTypeReference(<ExpressionWithTypeArguments>node);
|
||||
case SyntaxKind.TypeQuery:
|
||||
@@ -11354,21 +11345,8 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate {
|
||||
if (isIdentifierTypePredicate(predicate)) {
|
||||
return {
|
||||
kind: TypePredicateKind.Identifier,
|
||||
parameterName: predicate.parameterName,
|
||||
parameterIndex: predicate.parameterIndex,
|
||||
type: instantiateType(predicate.type, mapper)
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
kind: TypePredicateKind.This,
|
||||
type: instantiateType(predicate.type, mapper)
|
||||
};
|
||||
}
|
||||
function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): TypePredicate {
|
||||
return createTypePredicate(predicate.kind, predicate.parameterName, predicate.parameterIndex, instantiateType(predicate.type, mapper));
|
||||
}
|
||||
|
||||
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
|
||||
@@ -12422,7 +12400,7 @@ namespace ts {
|
||||
// with respect to T.
|
||||
const sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
|
||||
const targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType));
|
||||
const callbacks = sourceSig && targetSig && !signatureHasTypePredicate(sourceSig) && !signatureHasTypePredicate(targetSig) &&
|
||||
const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) &&
|
||||
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
|
||||
const related = callbacks ?
|
||||
// TODO: GH#18217 It will work if they're both `undefined`, but not if only one is
|
||||
@@ -12496,7 +12474,7 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
if (source.kind === TypePredicateKind.Identifier) {
|
||||
if (source.kind === TypePredicateKind.Identifier || source.kind === TypePredicateKind.AssertsIdentifier) {
|
||||
if (source.parameterIndex !== (target as IdentifierTypePredicate).parameterIndex) {
|
||||
if (reportErrors) {
|
||||
errorReporter!(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, (target as IdentifierTypePredicate).parameterName);
|
||||
@@ -12506,7 +12484,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const related = compareTypes(source.type, target.type, reportErrors);
|
||||
const related = source.type === target.type ? Ternary.True :
|
||||
source.type && target.type ? compareTypes(source.type, target.type, reportErrors) :
|
||||
Ternary.False;
|
||||
if (related === Ternary.False && reportErrors) {
|
||||
errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
|
||||
}
|
||||
@@ -14893,16 +14873,18 @@ namespace ts {
|
||||
if (!ignoreReturnTypes) {
|
||||
const sourceTypePredicate = getTypePredicateOfSignature(source);
|
||||
const targetTypePredicate = getTypePredicateOfSignature(target);
|
||||
result &= sourceTypePredicate !== undefined || targetTypePredicate !== undefined
|
||||
? compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes)
|
||||
// If they're both type predicates their return types will both be `boolean`, so no need to compare those.
|
||||
: compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
|
||||
result &= sourceTypePredicate || targetTypePredicate ?
|
||||
compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes) :
|
||||
compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function compareTypePredicatesIdentical(source: TypePredicate | undefined, target: TypePredicate | undefined, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
|
||||
return source === undefined || target === undefined || !typePredicateKindsMatch(source, target) ? Ternary.False : compareTypes(source.type, target.type);
|
||||
return !(source && target && typePredicateKindsMatch(source, target)) ? Ternary.False :
|
||||
source.type === target.type ? Ternary.True :
|
||||
source.type && target.type ? compareTypes(source.type, target.type) :
|
||||
Ternary.False;
|
||||
}
|
||||
|
||||
function literalTypesWithSameBaseType(types: Type[]): boolean {
|
||||
@@ -15510,8 +15492,7 @@ namespace ts {
|
||||
function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
|
||||
const sourceTypePredicate = getTypePredicateOfSignature(source);
|
||||
const targetTypePredicate = getTypePredicateOfSignature(target);
|
||||
if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind &&
|
||||
(sourceTypePredicate.kind === TypePredicateKind.This || sourceTypePredicate.parameterIndex === (<IdentifierTypePredicate>targetTypePredicate).parameterIndex)) {
|
||||
if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
|
||||
callback(sourceTypePredicate.type, targetTypePredicate.type);
|
||||
}
|
||||
else {
|
||||
@@ -17127,23 +17108,64 @@ namespace ts {
|
||||
return isLengthPushOrUnshift || isElementAssignment;
|
||||
}
|
||||
|
||||
function maybeTypePredicateCall(node: CallExpression) {
|
||||
const links = getNodeLinks(node);
|
||||
if (links.maybeTypePredicate === undefined) {
|
||||
links.maybeTypePredicate = getMaybeTypePredicate(node);
|
||||
}
|
||||
return links.maybeTypePredicate;
|
||||
function isDeclarationWithExplicitTypeAnnotation(declaration: Declaration | undefined) {
|
||||
return !!(declaration && (
|
||||
declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter ||
|
||||
declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) &&
|
||||
getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature));
|
||||
}
|
||||
|
||||
function getMaybeTypePredicate(node: CallExpression) {
|
||||
if (node.expression.kind !== SyntaxKind.SuperKeyword) {
|
||||
const funcType = checkNonNullExpression(node.expression);
|
||||
if (funcType !== silentNeverType) {
|
||||
const apparentType = getApparentType(funcType);
|
||||
return apparentType !== errorType && some(getSignaturesOfType(apparentType, SignatureKind.Call), signatureHasTypePredicate);
|
||||
function getExplicitTypeOfSymbol(symbol: Symbol) {
|
||||
return symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule) ||
|
||||
symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property) && isDeclarationWithExplicitTypeAnnotation(symbol.valueDeclaration) ?
|
||||
getTypeOfSymbol(symbol) : undefined;
|
||||
}
|
||||
|
||||
// We require the dotted function name in an assertion expression to be comprised of identifiers
|
||||
// that reference function, method, class or value module symbols; or variable, property or
|
||||
// parameter symbols with declarations that have explicit type annotations. Such references are
|
||||
// resolvable with no possibility of triggering circularities in control flow analysis.
|
||||
function getTypeOfDottedName(node: Expression): Type | undefined {
|
||||
if (!(node.flags & NodeFlags.InWithStatement)) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
const symbol = getResolvedSymbol(<Identifier>node);
|
||||
return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return checkThisExpression(node);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
const type = getTypeOfDottedName((<PropertyAccessExpression>node).expression);
|
||||
const prop = type && getPropertyOfType(type, (<PropertyAccessExpression>node).name.escapedText);
|
||||
return prop && getExplicitTypeOfSymbol(prop);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return getTypeOfDottedName((<ParenthesizedExpression>node).expression);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getEffectsSignature(node: CallExpression) {
|
||||
const links = getNodeLinks(node);
|
||||
let signature = links.effectsSignature;
|
||||
if (signature === undefined) {
|
||||
// A call expression parented by an expression statement is a potential assertion. Other call
|
||||
// expressions are potential type predicate function calls. In order to avoid triggering
|
||||
// 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) :
|
||||
node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) :
|
||||
undefined;
|
||||
const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, SignatureKind.Call);
|
||||
const candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] :
|
||||
some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) :
|
||||
undefined;
|
||||
signature = links.effectsSignature = candidate && hasTypePredicateOrNeverReturnType(candidate) ? candidate : unknownSignature;
|
||||
}
|
||||
return signature === unknownSignature ? undefined : signature;
|
||||
}
|
||||
|
||||
function hasTypePredicateOrNeverReturnType(signature: Signature) {
|
||||
return !!(getTypePredicateOfSignature(signature) ||
|
||||
signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & TypeFlags.Never);
|
||||
}
|
||||
|
||||
function reportFlowControlError(node: Node) {
|
||||
@@ -17153,6 +17175,71 @@ namespace ts {
|
||||
diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
|
||||
}
|
||||
|
||||
function isReachableFlowNode(flow: FlowNode) {
|
||||
const result = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false);
|
||||
lastFlowNode = flow;
|
||||
lastFlowNodeReachable = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function isUnlockedReachableFlowNode(flow: FlowNode) {
|
||||
return !(flow.flags & FlowFlags.PreFinally && (<PreFinallyFlow>flow).lock.locked) && isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false);
|
||||
}
|
||||
|
||||
function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean {
|
||||
while (true) {
|
||||
if (flow === lastFlowNode) {
|
||||
return lastFlowNodeReachable;
|
||||
}
|
||||
const flags = flow.flags;
|
||||
if (flags & FlowFlags.Shared) {
|
||||
if (!noCacheCheck) {
|
||||
const id = getFlowNodeId(flow);
|
||||
const reachable = flowNodeReachable[id];
|
||||
return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ true));
|
||||
}
|
||||
noCacheCheck = false;
|
||||
}
|
||||
if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.PreFinally)) {
|
||||
flow = (<FlowAssignment | FlowCondition | FlowArrayMutation | PreFinallyFlow>flow).antecedent;
|
||||
}
|
||||
else if (flags & FlowFlags.Call) {
|
||||
const signature = getEffectsSignature((<FlowCall>flow).node);
|
||||
if (signature && getReturnTypeOfSignature(signature).flags & TypeFlags.Never) {
|
||||
return false;
|
||||
}
|
||||
flow = (<FlowCall>flow).antecedent;
|
||||
}
|
||||
else if (flags & FlowFlags.BranchLabel) {
|
||||
// A branching point is reachable if any branch is reachable.
|
||||
return some((<FlowLabel>flow).antecedents, isUnlockedReachableFlowNode);
|
||||
}
|
||||
else if (flags & FlowFlags.LoopLabel) {
|
||||
// A loop is reachable if the control flow path that leads to the top is reachable.
|
||||
flow = (<FlowLabel>flow).antecedents![0];
|
||||
}
|
||||
else if (flags & FlowFlags.SwitchClause) {
|
||||
// The control flow path representing an unmatched value in a switch statement with
|
||||
// no default clause is unreachable if the switch statement is exhaustive.
|
||||
if ((<FlowSwitchClause>flow).clauseStart === (<FlowSwitchClause>flow).clauseEnd && isExhaustiveSwitchStatement((<FlowSwitchClause>flow).switchStatement)) {
|
||||
return false;
|
||||
}
|
||||
flow = (<FlowSwitchClause>flow).antecedent;
|
||||
}
|
||||
else if (flags & FlowFlags.AfterFinally) {
|
||||
// Cache is unreliable once we start locking nodes
|
||||
lastFlowNode = undefined;
|
||||
(<AfterFinallyFlow>flow).locked = true;
|
||||
const result = isReachableFlowNodeWorker((<AfterFinallyFlow>flow).antecedent, /*skipCacheCheck*/ false);
|
||||
(<AfterFinallyFlow>flow).locked = false;
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return !(flags & FlowFlags.Unreachable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, couldBeUninitialized?: boolean) {
|
||||
let key: string | undefined;
|
||||
let keySet = false;
|
||||
@@ -17172,7 +17259,7 @@ namespace ts {
|
||||
// on empty arrays are possible without implicit any errors and new element types can be inferred without
|
||||
// type mismatch errors.
|
||||
const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType);
|
||||
if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
if (resultType === unreachableNeverType|| reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
return declaredType;
|
||||
}
|
||||
return resultType;
|
||||
@@ -17227,6 +17314,13 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (flags & FlowFlags.Call) {
|
||||
type = getTypeAtFlowCall(<FlowCall>flow);
|
||||
if (!type) {
|
||||
flow = (<FlowCall>flow).antecedent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (flags & FlowFlags.Condition) {
|
||||
type = getTypeAtFlowCondition(<FlowCondition>flow);
|
||||
}
|
||||
@@ -17251,7 +17345,7 @@ namespace ts {
|
||||
}
|
||||
else if (flags & FlowFlags.Start) {
|
||||
// Check if we should continue with the control flow of the containing function.
|
||||
const container = (<FlowStart>flow).container;
|
||||
const container = (<FlowStart>flow).node;
|
||||
if (container && container !== flowContainer &&
|
||||
reference.kind !== SyntaxKind.PropertyAccessExpression &&
|
||||
reference.kind !== SyntaxKind.ElementAccessExpression &&
|
||||
@@ -17304,6 +17398,9 @@ namespace ts {
|
||||
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
|
||||
// only need to evaluate the assigned type if the declared type is a union type.
|
||||
if (isMatchingReference(reference, node)) {
|
||||
if (!isReachableFlowNode(flow)) {
|
||||
return unreachableNeverType;
|
||||
}
|
||||
if (getAssignmentTargetKind(node) === AssignmentKind.Compound) {
|
||||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
|
||||
@@ -17325,6 +17422,9 @@ namespace ts {
|
||||
// reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
|
||||
// return the declared type.
|
||||
if (containsMatchingReference(reference, node)) {
|
||||
if (!isReachableFlowNode(flow)) {
|
||||
return unreachableNeverType;
|
||||
}
|
||||
// A matching dotted name might also be an expando property on a function *expression*,
|
||||
// in which case we continue control flow analysis back to the function's declaration
|
||||
if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
|
||||
@@ -17343,6 +17443,38 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function narrowTypeByAssertion(type: Type, expr: Expression): Type {
|
||||
const node = skipParentheses(expr);
|
||||
if (node.kind === SyntaxKind.BinaryExpression) {
|
||||
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
|
||||
return narrowTypeByAssertion(narrowTypeByAssertion(type, (<BinaryExpression>node).left), (<BinaryExpression>node).right);
|
||||
}
|
||||
if ((<BinaryExpression>node).operatorToken.kind === SyntaxKind.BarBarToken) {
|
||||
return getUnionType([narrowTypeByAssertion(type, (<BinaryExpression>node).left), narrowTypeByAssertion(type, (<BinaryExpression>node).right)]);
|
||||
}
|
||||
}
|
||||
return narrowType(type, node, /*assumeTrue*/ true);
|
||||
}
|
||||
|
||||
function getTypeAtFlowCall(flow: FlowCall): FlowType | undefined {
|
||||
const signature = getEffectsSignature(flow.node);
|
||||
if (signature) {
|
||||
const predicate = getTypePredicateOfSignature(signature);
|
||||
if (predicate && (predicate.kind === TypePredicateKind.AssertsThis || predicate.kind === TypePredicateKind.AssertsIdentifier)) {
|
||||
const flowType = getTypeAtFlowNode(flow.antecedent);
|
||||
const type = getTypeFromFlowType(flowType);
|
||||
const narrowedType = predicate.type ? narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) :
|
||||
predicate.kind === TypePredicateKind.AssertsIdentifier ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) :
|
||||
type;
|
||||
return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
|
||||
}
|
||||
if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) {
|
||||
return unreachableNeverType;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType | undefined {
|
||||
if (declaredType === autoType || declaredType === autoArrayType) {
|
||||
const node = flow.node;
|
||||
@@ -17389,7 +17521,7 @@ namespace ts {
|
||||
// *only* place a silent never type is ever generated.
|
||||
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
|
||||
const nonEvolvingType = finalizeEvolvingArrayType(type);
|
||||
const narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue);
|
||||
const narrowedType = narrowType(nonEvolvingType, flow.node, assumeTrue);
|
||||
if (narrowedType === nonEvolvingType) {
|
||||
return flowType;
|
||||
}
|
||||
@@ -17417,6 +17549,9 @@ namespace ts {
|
||||
else if (containsMatchingReferenceDiscriminant(reference, expr)) {
|
||||
type = declaredType;
|
||||
}
|
||||
else if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
|
||||
return unreachableNeverType;
|
||||
}
|
||||
return createFlowType(type, isIncomplete(flowType));
|
||||
}
|
||||
|
||||
@@ -17933,24 +18068,25 @@ namespace ts {
|
||||
getIntersectionType([type, candidate]);
|
||||
}
|
||||
|
||||
function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type {
|
||||
if (!hasMatchingArgument(callExpression, reference) || !maybeTypePredicateCall(callExpression)) {
|
||||
return type;
|
||||
}
|
||||
const signature = getResolvedSignature(callExpression);
|
||||
const predicate = getTypePredicateOfSignature(signature);
|
||||
if (!predicate) {
|
||||
return type;
|
||||
function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type {
|
||||
if (hasMatchingArgument(callExpression, reference)) {
|
||||
const signature = getEffectsSignature(callExpression);
|
||||
const predicate = signature && getTypePredicateOfSignature(signature);
|
||||
if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) {
|
||||
return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByTypePredicate(type: Type, predicate: TypePredicate, callExpression: CallExpression, assumeTrue: boolean): Type {
|
||||
// Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
|
||||
if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
if (isIdentifierTypePredicate(predicate)) {
|
||||
if (predicate.kind === TypePredicateKind.Identifier || predicate.kind === TypePredicateKind.AssertsIdentifier) {
|
||||
const predicateArgument = callExpression.arguments[predicate.parameterIndex];
|
||||
if (predicateArgument) {
|
||||
if (predicateArgument && predicate.type) {
|
||||
if (isMatchingReference(reference, predicateArgument)) {
|
||||
return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
|
||||
}
|
||||
@@ -17961,7 +18097,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const invokedExpression = skipParentheses(callExpression.expression);
|
||||
if (isAccessExpression(invokedExpression)) {
|
||||
if (isAccessExpression(invokedExpression) && predicate.type) {
|
||||
const possibleReference = skipParentheses(invokedExpression.expression);
|
||||
if (isMatchingReference(reference, possibleReference)) {
|
||||
return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
|
||||
@@ -17985,7 +18121,7 @@ namespace ts {
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return narrowTypeByTruthiness(type, expr, assumeTrue);
|
||||
case SyntaxKind.CallExpression:
|
||||
return narrowTypeByTypePredicate(type, <CallExpression>expr, assumeTrue);
|
||||
return narrowTypeByCallExpression(type, <CallExpression>expr, assumeTrue);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
@@ -23871,9 +24007,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isExhaustiveSwitchStatement(node: SwitchStatement): boolean {
|
||||
if (!node.possiblyExhaustive) {
|
||||
return false;
|
||||
}
|
||||
const links = getNodeLinks(node);
|
||||
return links.isExhaustive !== undefined ? links.isExhaustive : (links.isExhaustive = computeExhaustiveSwitchStatement(node));
|
||||
}
|
||||
|
||||
function computeExhaustiveSwitchStatement(node: SwitchStatement): boolean {
|
||||
if (node.expression.kind === SyntaxKind.TypeOfExpression) {
|
||||
const operandType = getTypeOfExpression((node.expression as TypeOfExpression).expression);
|
||||
// This cast is safe because the switch is possibly exhaustive and does not contain a default case, so there can be no undefined.
|
||||
@@ -23895,14 +24033,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
|
||||
if (!(func.flags & NodeFlags.HasImplicitReturn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (some((<Block>func.body).statements, statement => statement.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(<SwitchStatement>statement))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return func.endFlowNode && isReachableFlowNode(func.endFlowNode);
|
||||
}
|
||||
|
||||
/** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */
|
||||
@@ -25728,7 +25859,7 @@ namespace ts {
|
||||
checkSourceElement(node.type);
|
||||
|
||||
const { parameterName } = node;
|
||||
if (isThisTypePredicate(typePredicate)) {
|
||||
if (typePredicate.kind === TypePredicateKind.This || typePredicate.kind === TypePredicateKind.AssertsThis) {
|
||||
getTypeFromThisTypeNode(parameterName as ThisTypeNode);
|
||||
}
|
||||
else {
|
||||
@@ -25737,12 +25868,14 @@ namespace ts {
|
||||
error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
|
||||
}
|
||||
else {
|
||||
const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type);
|
||||
checkTypeAssignableTo(typePredicate.type,
|
||||
getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]),
|
||||
node.type,
|
||||
/*headMessage*/ undefined,
|
||||
leadingError);
|
||||
if (typePredicate.type) {
|
||||
const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type);
|
||||
checkTypeAssignableTo(typePredicate.type,
|
||||
getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]),
|
||||
node.type,
|
||||
/*headMessage*/ undefined,
|
||||
leadingError);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parameterName) {
|
||||
@@ -30608,6 +30741,9 @@ namespace ts {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && node.flowNode && !isReachableFlowNode(node.flowNode)) {
|
||||
errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, Diagnostics.Unreachable_code_detected);
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case SyntaxKind.TypeParameter:
|
||||
@@ -31606,8 +31742,7 @@ namespace ts {
|
||||
const nameType = checkComputedPropertyName(name);
|
||||
return isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike) ? nameType : stringType;
|
||||
default:
|
||||
Debug.fail("Unsupported property name.");
|
||||
return errorType;
|
||||
return Debug.fail("Unsupported property name.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -1946,11 +1946,17 @@ namespace ts {
|
||||
//
|
||||
|
||||
function emitTypePredicate(node: TypePredicateNode) {
|
||||
if (node.assertsModifier) {
|
||||
emit(node.assertsModifier);
|
||||
writeSpace();
|
||||
}
|
||||
emit(node.parameterName);
|
||||
writeSpace();
|
||||
writeKeyword("is");
|
||||
writeSpace();
|
||||
emit(node.type);
|
||||
if (node.type) {
|
||||
writeSpace();
|
||||
writeKeyword("is");
|
||||
writeSpace();
|
||||
emit(node.type);
|
||||
}
|
||||
}
|
||||
|
||||
function emitTypeReference(node: TypeReferenceNode) {
|
||||
|
||||
+12
-2
@@ -669,16 +669,26 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) {
|
||||
return createTypePredicateNodeWithModifier(/*assertsModifier*/ undefined, parameterName, type);
|
||||
}
|
||||
|
||||
export function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) {
|
||||
const node = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode;
|
||||
node.assertsModifier = assertsModifier;
|
||||
node.parameterName = asName(parameterName);
|
||||
node.type = type;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) {
|
||||
return node.parameterName !== parameterName
|
||||
return updateTypePredicateNodeWithModifier(node, node.assertsModifier, parameterName, type);
|
||||
}
|
||||
|
||||
export function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) {
|
||||
return node.assertsModifier !== assertsModifier
|
||||
|| node.parameterName !== parameterName
|
||||
|| node.type !== type
|
||||
? updateNode(createTypePredicateNode(parameterName, type), node)
|
||||
? updateNode(createTypePredicateNodeWithModifier(assertsModifier, parameterName, type), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -165,7 +165,8 @@ namespace ts {
|
||||
return visitNode(cbNode, (<TypeReferenceNode>node).typeName) ||
|
||||
visitNodes(cbNode, cbNodes, (<TypeReferenceNode>node).typeArguments);
|
||||
case SyntaxKind.TypePredicate:
|
||||
return visitNode(cbNode, (<TypePredicateNode>node).parameterName) ||
|
||||
return visitNode(cbNode, (<TypePredicateNode>node).assertsModifier) ||
|
||||
visitNode(cbNode, (<TypePredicateNode>node).parameterName) ||
|
||||
visitNode(cbNode, (<TypePredicateNode>node).type);
|
||||
case SyntaxKind.TypeQuery:
|
||||
return visitNode(cbNode, (<TypeQueryNode>node).exprName);
|
||||
@@ -3041,6 +3042,8 @@ namespace ts {
|
||||
return parseParenthesizedType();
|
||||
case SyntaxKind.ImportKeyword:
|
||||
return parseImportType();
|
||||
case SyntaxKind.AssertsKeyword:
|
||||
return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference();
|
||||
default:
|
||||
return parseTypeReference();
|
||||
}
|
||||
@@ -3081,6 +3084,7 @@ namespace ts {
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
case SyntaxKind.InferKeyword:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.AssertsKeyword:
|
||||
return true;
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return !inStartOfParameter;
|
||||
@@ -3257,6 +3261,7 @@ namespace ts {
|
||||
const type = parseType();
|
||||
if (typePredicateVariable) {
|
||||
const node = <TypePredicateNode>createNode(SyntaxKind.TypePredicate, typePredicateVariable.pos);
|
||||
node.assertsModifier = undefined;
|
||||
node.parameterName = typePredicateVariable;
|
||||
node.type = type;
|
||||
return finishNode(node);
|
||||
@@ -3274,6 +3279,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseAssertsTypePredicate(): TypeNode {
|
||||
const node = <TypePredicateNode>createNode(SyntaxKind.TypePredicate);
|
||||
node.assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword);
|
||||
node.parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier();
|
||||
node.type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined;
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseType(): TypeNode {
|
||||
// The rules about 'yield' only apply to actual code/expression contexts. They don't
|
||||
// apply to 'type' contexts. So we disable these parameters here before moving on.
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace ts {
|
||||
abstract: SyntaxKind.AbstractKeyword,
|
||||
any: SyntaxKind.AnyKeyword,
|
||||
as: SyntaxKind.AsKeyword,
|
||||
asserts: SyntaxKind.AssertsKeyword,
|
||||
bigint: SyntaxKind.BigIntKeyword,
|
||||
boolean: SyntaxKind.BooleanKeyword,
|
||||
break: SyntaxKind.BreakKeyword,
|
||||
|
||||
@@ -2871,7 +2871,7 @@ namespace ts {
|
||||
function tryEnterOrLeaveBlock(operationIndex: number): void {
|
||||
if (blocks) {
|
||||
for (; blockIndex < blockActions!.length && blockOffsets![blockIndex] <= operationIndex; blockIndex++) {
|
||||
const block = blocks[blockIndex];
|
||||
const block: CodeBlock = blocks[blockIndex];
|
||||
const blockAction = blockActions![blockIndex];
|
||||
switch (block.kind) {
|
||||
case CodeBlockKind.Exception:
|
||||
|
||||
+64
-21
@@ -32,6 +32,7 @@ namespace ts {
|
||||
| SyntaxKind.AbstractKeyword
|
||||
| SyntaxKind.AnyKeyword
|
||||
| SyntaxKind.AsKeyword
|
||||
| SyntaxKind.AssertsKeyword
|
||||
| SyntaxKind.BigIntKeyword
|
||||
| SyntaxKind.BooleanKeyword
|
||||
| SyntaxKind.BreakKeyword
|
||||
@@ -250,6 +251,7 @@ namespace ts {
|
||||
// Contextual keywords
|
||||
AbstractKeyword,
|
||||
AsKeyword,
|
||||
AssertsKeyword,
|
||||
AnyKeyword,
|
||||
AsyncKeyword,
|
||||
AwaitKeyword,
|
||||
@@ -361,8 +363,8 @@ namespace ts {
|
||||
SemicolonClassElement,
|
||||
// Element
|
||||
Block,
|
||||
VariableStatement,
|
||||
EmptyStatement,
|
||||
VariableStatement,
|
||||
ExpressionStatement,
|
||||
IfStatement,
|
||||
DoStatement,
|
||||
@@ -512,6 +514,8 @@ namespace ts {
|
||||
LastTemplateToken = TemplateTail,
|
||||
FirstBinaryOperator = LessThanToken,
|
||||
LastBinaryOperator = CaretEqualsToken,
|
||||
FirstStatement = VariableStatement,
|
||||
LastStatement = DebuggerStatement,
|
||||
FirstNode = QualifiedName,
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocPropertyTag,
|
||||
@@ -740,6 +744,7 @@ namespace ts {
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
export type PlusToken = Token<SyntaxKind.PlusToken>;
|
||||
export type MinusToken = Token<SyntaxKind.MinusToken>;
|
||||
export type AssertsToken = Token<SyntaxKind.AssertsKeyword>;
|
||||
|
||||
export type Modifier
|
||||
= Token<SyntaxKind.AbstractKeyword>
|
||||
@@ -1041,6 +1046,7 @@ namespace ts {
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
/* @internal */ endFlowNode?: FlowNode;
|
||||
}
|
||||
|
||||
export type FunctionLikeDeclaration =
|
||||
@@ -1184,8 +1190,9 @@ namespace ts {
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent: SignatureDeclaration | JSDocTypeExpression;
|
||||
assertsModifier?: AssertsToken;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
type?: TypeNode;
|
||||
}
|
||||
|
||||
export interface TypeQueryNode extends TypeNode {
|
||||
@@ -2574,16 +2581,33 @@ namespace ts {
|
||||
FalseCondition = 1 << 6, // Condition known to be false
|
||||
SwitchClause = 1 << 7, // Switch statement clause
|
||||
ArrayMutation = 1 << 8, // Potential array mutation
|
||||
Referenced = 1 << 9, // Referenced as antecedent once
|
||||
Shared = 1 << 10, // Referenced as antecedent more than once
|
||||
PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow
|
||||
AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph
|
||||
Call = 1 << 9, // Potential assertion call
|
||||
Referenced = 1 << 10, // Referenced as antecedent once
|
||||
Shared = 1 << 11, // Referenced as antecedent more than once
|
||||
PreFinally = 1 << 12, // Injected edge that links pre-finally label and pre-try flow
|
||||
AfterFinally = 1 << 13, // Injected edge that links post-finally flow with the rest of the graph
|
||||
/** @internal */
|
||||
Cached = 1 << 13, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant
|
||||
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
|
||||
}
|
||||
|
||||
export type FlowNode =
|
||||
| AfterFinallyFlow
|
||||
| PreFinallyFlow
|
||||
| FlowStart
|
||||
| FlowLabel
|
||||
| FlowAssignment
|
||||
| FlowCall
|
||||
| FlowCondition
|
||||
| FlowSwitchClause
|
||||
| FlowArrayMutation;
|
||||
|
||||
export interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number; // Node id used by flow type cache in checker
|
||||
}
|
||||
|
||||
export interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
@@ -2597,18 +2621,11 @@ namespace ts {
|
||||
lock: FlowLock;
|
||||
}
|
||||
|
||||
export type FlowNode =
|
||||
| AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
export interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number; // Node id used by flow type cache in checker
|
||||
}
|
||||
|
||||
// FlowStart represents the start of a control flow. For a function expression or arrow
|
||||
// function, the container property references the function (which in turn has a flowNode
|
||||
// function, the node property references the function (which in turn has a flowNode
|
||||
// property for the containing control flow).
|
||||
export interface FlowStart extends FlowNodeBase {
|
||||
container?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
node?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
}
|
||||
|
||||
// FlowLabel represents a junction with multiple possible preceding control flows.
|
||||
@@ -2623,10 +2640,15 @@ namespace ts {
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
export interface FlowCall extends FlowNodeBase {
|
||||
node: CallExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
// FlowCondition represents a condition that is known to be true or false at the
|
||||
// node's location in the control flow.
|
||||
export interface FlowCondition extends FlowNodeBase {
|
||||
expression: Expression;
|
||||
node: Expression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
@@ -3531,25 +3553,45 @@ namespace ts {
|
||||
|
||||
export const enum TypePredicateKind {
|
||||
This,
|
||||
Identifier
|
||||
Identifier,
|
||||
AssertsThis,
|
||||
AssertsIdentifier
|
||||
}
|
||||
|
||||
export interface TypePredicateBase {
|
||||
kind: TypePredicateKind;
|
||||
type: Type;
|
||||
type: Type | undefined;
|
||||
}
|
||||
|
||||
export interface ThisTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.This;
|
||||
parameterName: undefined;
|
||||
parameterIndex: undefined;
|
||||
type: Type;
|
||||
}
|
||||
|
||||
export interface IdentifierTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.Identifier;
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type;
|
||||
}
|
||||
|
||||
export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate;
|
||||
export interface AssertsThisTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.AssertsThis;
|
||||
parameterName: undefined;
|
||||
parameterIndex: undefined;
|
||||
type: Type | undefined;
|
||||
}
|
||||
|
||||
export interface AssertsIdentifierTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.AssertsIdentifier;
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type | undefined;
|
||||
}
|
||||
|
||||
export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate;
|
||||
|
||||
/* @internal */
|
||||
export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration;
|
||||
@@ -3967,7 +4009,7 @@ namespace ts {
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSymbol?: Symbol; // Cached name resolution result
|
||||
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
|
||||
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
|
||||
effectsSignature?: Signature; // Signature with possible control flow effects
|
||||
enumMemberValue?: string | number; // Constant value of enum member
|
||||
isVisible?: boolean; // Is this node visible
|
||||
containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference
|
||||
@@ -3982,6 +4024,7 @@ namespace ts {
|
||||
contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive
|
||||
deferredNodes?: Map<Node>; // Set of nodes whose checking has been deferred
|
||||
capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement
|
||||
isExhaustive?: boolean; // Is node an exhaustive switch statement
|
||||
}
|
||||
|
||||
export const enum TypeFlags {
|
||||
|
||||
@@ -333,7 +333,8 @@ namespace ts {
|
||||
|
||||
// Types
|
||||
case SyntaxKind.TypePredicate:
|
||||
return updateTypePredicateNode(<TypePredicateNode>node,
|
||||
return updateTypePredicateNodeWithModifier(<TypePredicateNode>node,
|
||||
visitNode((<TypePredicateNode>node).assertsModifier, visitor),
|
||||
visitNode((<TypePredicateNode>node).parameterName, visitor),
|
||||
visitNode((<TypePredicateNode>node).type, visitor, isTypeNode));
|
||||
|
||||
|
||||
+254
-224
@@ -73,7 +73,7 @@ declare namespace ts {
|
||||
end: number;
|
||||
}
|
||||
export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
|
||||
export enum SyntaxKind {
|
||||
Unknown = 0,
|
||||
@@ -198,206 +198,207 @@ declare namespace ts {
|
||||
YieldKeyword = 118,
|
||||
AbstractKeyword = 119,
|
||||
AsKeyword = 120,
|
||||
AnyKeyword = 121,
|
||||
AsyncKeyword = 122,
|
||||
AwaitKeyword = 123,
|
||||
BooleanKeyword = 124,
|
||||
ConstructorKeyword = 125,
|
||||
DeclareKeyword = 126,
|
||||
GetKeyword = 127,
|
||||
InferKeyword = 128,
|
||||
IsKeyword = 129,
|
||||
KeyOfKeyword = 130,
|
||||
ModuleKeyword = 131,
|
||||
NamespaceKeyword = 132,
|
||||
NeverKeyword = 133,
|
||||
ReadonlyKeyword = 134,
|
||||
RequireKeyword = 135,
|
||||
NumberKeyword = 136,
|
||||
ObjectKeyword = 137,
|
||||
SetKeyword = 138,
|
||||
StringKeyword = 139,
|
||||
SymbolKeyword = 140,
|
||||
TypeKeyword = 141,
|
||||
UndefinedKeyword = 142,
|
||||
UniqueKeyword = 143,
|
||||
UnknownKeyword = 144,
|
||||
FromKeyword = 145,
|
||||
GlobalKeyword = 146,
|
||||
BigIntKeyword = 147,
|
||||
OfKeyword = 148,
|
||||
QualifiedName = 149,
|
||||
ComputedPropertyName = 150,
|
||||
TypeParameter = 151,
|
||||
Parameter = 152,
|
||||
Decorator = 153,
|
||||
PropertySignature = 154,
|
||||
PropertyDeclaration = 155,
|
||||
MethodSignature = 156,
|
||||
MethodDeclaration = 157,
|
||||
Constructor = 158,
|
||||
GetAccessor = 159,
|
||||
SetAccessor = 160,
|
||||
CallSignature = 161,
|
||||
ConstructSignature = 162,
|
||||
IndexSignature = 163,
|
||||
TypePredicate = 164,
|
||||
TypeReference = 165,
|
||||
FunctionType = 166,
|
||||
ConstructorType = 167,
|
||||
TypeQuery = 168,
|
||||
TypeLiteral = 169,
|
||||
ArrayType = 170,
|
||||
TupleType = 171,
|
||||
OptionalType = 172,
|
||||
RestType = 173,
|
||||
UnionType = 174,
|
||||
IntersectionType = 175,
|
||||
ConditionalType = 176,
|
||||
InferType = 177,
|
||||
ParenthesizedType = 178,
|
||||
ThisType = 179,
|
||||
TypeOperator = 180,
|
||||
IndexedAccessType = 181,
|
||||
MappedType = 182,
|
||||
LiteralType = 183,
|
||||
ImportType = 184,
|
||||
ObjectBindingPattern = 185,
|
||||
ArrayBindingPattern = 186,
|
||||
BindingElement = 187,
|
||||
ArrayLiteralExpression = 188,
|
||||
ObjectLiteralExpression = 189,
|
||||
PropertyAccessExpression = 190,
|
||||
ElementAccessExpression = 191,
|
||||
CallExpression = 192,
|
||||
NewExpression = 193,
|
||||
TaggedTemplateExpression = 194,
|
||||
TypeAssertionExpression = 195,
|
||||
ParenthesizedExpression = 196,
|
||||
FunctionExpression = 197,
|
||||
ArrowFunction = 198,
|
||||
DeleteExpression = 199,
|
||||
TypeOfExpression = 200,
|
||||
VoidExpression = 201,
|
||||
AwaitExpression = 202,
|
||||
PrefixUnaryExpression = 203,
|
||||
PostfixUnaryExpression = 204,
|
||||
BinaryExpression = 205,
|
||||
ConditionalExpression = 206,
|
||||
TemplateExpression = 207,
|
||||
YieldExpression = 208,
|
||||
SpreadElement = 209,
|
||||
ClassExpression = 210,
|
||||
OmittedExpression = 211,
|
||||
ExpressionWithTypeArguments = 212,
|
||||
AsExpression = 213,
|
||||
NonNullExpression = 214,
|
||||
MetaProperty = 215,
|
||||
SyntheticExpression = 216,
|
||||
TemplateSpan = 217,
|
||||
SemicolonClassElement = 218,
|
||||
Block = 219,
|
||||
VariableStatement = 220,
|
||||
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,
|
||||
ExpressionStatement = 222,
|
||||
IfStatement = 223,
|
||||
DoStatement = 224,
|
||||
WhileStatement = 225,
|
||||
ForStatement = 226,
|
||||
ForInStatement = 227,
|
||||
ForOfStatement = 228,
|
||||
ContinueStatement = 229,
|
||||
BreakStatement = 230,
|
||||
ReturnStatement = 231,
|
||||
WithStatement = 232,
|
||||
SwitchStatement = 233,
|
||||
LabeledStatement = 234,
|
||||
ThrowStatement = 235,
|
||||
TryStatement = 236,
|
||||
DebuggerStatement = 237,
|
||||
VariableDeclaration = 238,
|
||||
VariableDeclarationList = 239,
|
||||
FunctionDeclaration = 240,
|
||||
ClassDeclaration = 241,
|
||||
InterfaceDeclaration = 242,
|
||||
TypeAliasDeclaration = 243,
|
||||
EnumDeclaration = 244,
|
||||
ModuleDeclaration = 245,
|
||||
ModuleBlock = 246,
|
||||
CaseBlock = 247,
|
||||
NamespaceExportDeclaration = 248,
|
||||
ImportEqualsDeclaration = 249,
|
||||
ImportDeclaration = 250,
|
||||
ImportClause = 251,
|
||||
NamespaceImport = 252,
|
||||
NamedImports = 253,
|
||||
ImportSpecifier = 254,
|
||||
ExportAssignment = 255,
|
||||
ExportDeclaration = 256,
|
||||
NamedExports = 257,
|
||||
ExportSpecifier = 258,
|
||||
MissingDeclaration = 259,
|
||||
ExternalModuleReference = 260,
|
||||
JsxElement = 261,
|
||||
JsxSelfClosingElement = 262,
|
||||
JsxOpeningElement = 263,
|
||||
JsxClosingElement = 264,
|
||||
JsxFragment = 265,
|
||||
JsxOpeningFragment = 266,
|
||||
JsxClosingFragment = 267,
|
||||
JsxAttribute = 268,
|
||||
JsxAttributes = 269,
|
||||
JsxSpreadAttribute = 270,
|
||||
JsxExpression = 271,
|
||||
CaseClause = 272,
|
||||
DefaultClause = 273,
|
||||
HeritageClause = 274,
|
||||
CatchClause = 275,
|
||||
PropertyAssignment = 276,
|
||||
ShorthandPropertyAssignment = 277,
|
||||
SpreadAssignment = 278,
|
||||
EnumMember = 279,
|
||||
UnparsedPrologue = 280,
|
||||
UnparsedPrepend = 281,
|
||||
UnparsedText = 282,
|
||||
UnparsedInternalText = 283,
|
||||
UnparsedSyntheticReference = 284,
|
||||
SourceFile = 285,
|
||||
Bundle = 286,
|
||||
UnparsedSource = 287,
|
||||
InputFiles = 288,
|
||||
JSDocTypeExpression = 289,
|
||||
JSDocAllType = 290,
|
||||
JSDocUnknownType = 291,
|
||||
JSDocNullableType = 292,
|
||||
JSDocNonNullableType = 293,
|
||||
JSDocOptionalType = 294,
|
||||
JSDocFunctionType = 295,
|
||||
JSDocVariadicType = 296,
|
||||
JSDocNamepathType = 297,
|
||||
JSDocComment = 298,
|
||||
JSDocTypeLiteral = 299,
|
||||
JSDocSignature = 300,
|
||||
JSDocTag = 301,
|
||||
JSDocAugmentsTag = 302,
|
||||
JSDocAuthorTag = 303,
|
||||
JSDocClassTag = 304,
|
||||
JSDocCallbackTag = 305,
|
||||
JSDocEnumTag = 306,
|
||||
JSDocParameterTag = 307,
|
||||
JSDocReturnTag = 308,
|
||||
JSDocThisTag = 309,
|
||||
JSDocTypeTag = 310,
|
||||
JSDocTemplateTag = 311,
|
||||
JSDocTypedefTag = 312,
|
||||
JSDocPropertyTag = 313,
|
||||
SyntaxList = 314,
|
||||
NotEmittedStatement = 315,
|
||||
PartiallyEmittedExpression = 316,
|
||||
CommaListExpression = 317,
|
||||
MergeDeclarationMarker = 318,
|
||||
EndOfDeclarationMarker = 319,
|
||||
Count = 320,
|
||||
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,
|
||||
@@ -405,15 +406,15 @@ declare namespace ts {
|
||||
FirstReservedWord = 74,
|
||||
LastReservedWord = 109,
|
||||
FirstKeyword = 74,
|
||||
LastKeyword = 148,
|
||||
LastKeyword = 149,
|
||||
FirstFutureReservedWord = 110,
|
||||
LastFutureReservedWord = 118,
|
||||
FirstTypeNode = 164,
|
||||
LastTypeNode = 184,
|
||||
FirstTypeNode = 165,
|
||||
LastTypeNode = 185,
|
||||
FirstPunctuation = 18,
|
||||
LastPunctuation = 72,
|
||||
FirstToken = 0,
|
||||
LastToken = 148,
|
||||
LastToken = 149,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
@@ -422,11 +423,13 @@ declare namespace ts {
|
||||
LastTemplateToken = 17,
|
||||
FirstBinaryOperator = 28,
|
||||
LastBinaryOperator = 72,
|
||||
FirstNode = 149,
|
||||
FirstJSDocNode = 289,
|
||||
LastJSDocNode = 313,
|
||||
FirstJSDocTagNode = 301,
|
||||
LastJSDocTagNode = 313,
|
||||
FirstStatement = 222,
|
||||
LastStatement = 238,
|
||||
FirstNode = 150,
|
||||
FirstJSDocNode = 290,
|
||||
LastJSDocNode = 314,
|
||||
FirstJSDocTagNode = 302,
|
||||
LastJSDocTagNode = 314,
|
||||
}
|
||||
export enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -517,6 +520,7 @@ declare namespace ts {
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
export type PlusToken = Token<SyntaxKind.PlusToken>;
|
||||
export type MinusToken = Token<SyntaxKind.MinusToken>;
|
||||
export type AssertsToken = Token<SyntaxKind.AssertsKeyword>;
|
||||
export type Modifier = Token<SyntaxKind.AbstractKeyword> | Token<SyntaxKind.AsyncKeyword> | Token<SyntaxKind.ConstKeyword> | Token<SyntaxKind.DeclareKeyword> | Token<SyntaxKind.DefaultKeyword> | Token<SyntaxKind.ExportKeyword> | Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword> | Token<SyntaxKind.ProtectedKeyword> | Token<SyntaxKind.ReadonlyKeyword> | Token<SyntaxKind.StaticKeyword>;
|
||||
export type ModifiersArray = NodeArray<Modifier>;
|
||||
export interface Identifier extends PrimaryExpression, Declaration {
|
||||
@@ -770,8 +774,9 @@ declare namespace ts {
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent: SignatureDeclaration | JSDocTypeExpression;
|
||||
assertsModifier?: AssertsToken;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
type?: TypeNode;
|
||||
}
|
||||
export interface TypeQueryNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeQuery;
|
||||
@@ -1669,13 +1674,19 @@ declare namespace ts {
|
||||
FalseCondition = 64,
|
||||
SwitchClause = 128,
|
||||
ArrayMutation = 256,
|
||||
Referenced = 512,
|
||||
Shared = 1024,
|
||||
PreFinally = 2048,
|
||||
AfterFinally = 4096,
|
||||
Call = 512,
|
||||
Referenced = 1024,
|
||||
Shared = 2048,
|
||||
PreFinally = 4096,
|
||||
AfterFinally = 8192,
|
||||
Label = 12,
|
||||
Condition = 96
|
||||
}
|
||||
export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
export interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
export interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
@@ -1686,13 +1697,8 @@ declare namespace ts {
|
||||
antecedent: FlowNode;
|
||||
lock: FlowLock;
|
||||
}
|
||||
export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
export interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
export interface FlowStart extends FlowNodeBase {
|
||||
container?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
node?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
}
|
||||
export interface FlowLabel extends FlowNodeBase {
|
||||
antecedents: FlowNode[] | undefined;
|
||||
@@ -1701,8 +1707,12 @@ declare namespace ts {
|
||||
node: Expression | VariableDeclaration | BindingElement;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
export interface FlowCall extends FlowNodeBase {
|
||||
node: CallExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
export interface FlowCondition extends FlowNodeBase {
|
||||
expression: Expression;
|
||||
node: Expression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
export interface FlowSwitchClause extends FlowNodeBase {
|
||||
@@ -2098,21 +2108,39 @@ declare namespace ts {
|
||||
}
|
||||
export enum TypePredicateKind {
|
||||
This = 0,
|
||||
Identifier = 1
|
||||
Identifier = 1,
|
||||
AssertsThis = 2,
|
||||
AssertsIdentifier = 3
|
||||
}
|
||||
export interface TypePredicateBase {
|
||||
kind: TypePredicateKind;
|
||||
type: Type;
|
||||
type: Type | undefined;
|
||||
}
|
||||
export interface ThisTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.This;
|
||||
parameterName: undefined;
|
||||
parameterIndex: undefined;
|
||||
type: Type;
|
||||
}
|
||||
export interface IdentifierTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.Identifier;
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type;
|
||||
}
|
||||
export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate;
|
||||
export interface AssertsThisTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.AssertsThis;
|
||||
parameterName: undefined;
|
||||
parameterIndex: undefined;
|
||||
type: Type | undefined;
|
||||
}
|
||||
export interface AssertsIdentifierTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.AssertsIdentifier;
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type | undefined;
|
||||
}
|
||||
export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate;
|
||||
export enum SymbolFlags {
|
||||
None = 0,
|
||||
FunctionScopedVariable = 1,
|
||||
@@ -3845,7 +3873,9 @@ declare namespace ts {
|
||||
function updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode;
|
||||
function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode;
|
||||
function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode;
|
||||
function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode;
|
||||
function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode;
|
||||
function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined): TypeReferenceNode;
|
||||
function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray<TypeNode> | undefined): TypeReferenceNode;
|
||||
function createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode;
|
||||
|
||||
+254
-224
@@ -73,7 +73,7 @@ declare namespace ts {
|
||||
end: number;
|
||||
}
|
||||
export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword;
|
||||
export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken;
|
||||
export enum SyntaxKind {
|
||||
Unknown = 0,
|
||||
@@ -198,206 +198,207 @@ declare namespace ts {
|
||||
YieldKeyword = 118,
|
||||
AbstractKeyword = 119,
|
||||
AsKeyword = 120,
|
||||
AnyKeyword = 121,
|
||||
AsyncKeyword = 122,
|
||||
AwaitKeyword = 123,
|
||||
BooleanKeyword = 124,
|
||||
ConstructorKeyword = 125,
|
||||
DeclareKeyword = 126,
|
||||
GetKeyword = 127,
|
||||
InferKeyword = 128,
|
||||
IsKeyword = 129,
|
||||
KeyOfKeyword = 130,
|
||||
ModuleKeyword = 131,
|
||||
NamespaceKeyword = 132,
|
||||
NeverKeyword = 133,
|
||||
ReadonlyKeyword = 134,
|
||||
RequireKeyword = 135,
|
||||
NumberKeyword = 136,
|
||||
ObjectKeyword = 137,
|
||||
SetKeyword = 138,
|
||||
StringKeyword = 139,
|
||||
SymbolKeyword = 140,
|
||||
TypeKeyword = 141,
|
||||
UndefinedKeyword = 142,
|
||||
UniqueKeyword = 143,
|
||||
UnknownKeyword = 144,
|
||||
FromKeyword = 145,
|
||||
GlobalKeyword = 146,
|
||||
BigIntKeyword = 147,
|
||||
OfKeyword = 148,
|
||||
QualifiedName = 149,
|
||||
ComputedPropertyName = 150,
|
||||
TypeParameter = 151,
|
||||
Parameter = 152,
|
||||
Decorator = 153,
|
||||
PropertySignature = 154,
|
||||
PropertyDeclaration = 155,
|
||||
MethodSignature = 156,
|
||||
MethodDeclaration = 157,
|
||||
Constructor = 158,
|
||||
GetAccessor = 159,
|
||||
SetAccessor = 160,
|
||||
CallSignature = 161,
|
||||
ConstructSignature = 162,
|
||||
IndexSignature = 163,
|
||||
TypePredicate = 164,
|
||||
TypeReference = 165,
|
||||
FunctionType = 166,
|
||||
ConstructorType = 167,
|
||||
TypeQuery = 168,
|
||||
TypeLiteral = 169,
|
||||
ArrayType = 170,
|
||||
TupleType = 171,
|
||||
OptionalType = 172,
|
||||
RestType = 173,
|
||||
UnionType = 174,
|
||||
IntersectionType = 175,
|
||||
ConditionalType = 176,
|
||||
InferType = 177,
|
||||
ParenthesizedType = 178,
|
||||
ThisType = 179,
|
||||
TypeOperator = 180,
|
||||
IndexedAccessType = 181,
|
||||
MappedType = 182,
|
||||
LiteralType = 183,
|
||||
ImportType = 184,
|
||||
ObjectBindingPattern = 185,
|
||||
ArrayBindingPattern = 186,
|
||||
BindingElement = 187,
|
||||
ArrayLiteralExpression = 188,
|
||||
ObjectLiteralExpression = 189,
|
||||
PropertyAccessExpression = 190,
|
||||
ElementAccessExpression = 191,
|
||||
CallExpression = 192,
|
||||
NewExpression = 193,
|
||||
TaggedTemplateExpression = 194,
|
||||
TypeAssertionExpression = 195,
|
||||
ParenthesizedExpression = 196,
|
||||
FunctionExpression = 197,
|
||||
ArrowFunction = 198,
|
||||
DeleteExpression = 199,
|
||||
TypeOfExpression = 200,
|
||||
VoidExpression = 201,
|
||||
AwaitExpression = 202,
|
||||
PrefixUnaryExpression = 203,
|
||||
PostfixUnaryExpression = 204,
|
||||
BinaryExpression = 205,
|
||||
ConditionalExpression = 206,
|
||||
TemplateExpression = 207,
|
||||
YieldExpression = 208,
|
||||
SpreadElement = 209,
|
||||
ClassExpression = 210,
|
||||
OmittedExpression = 211,
|
||||
ExpressionWithTypeArguments = 212,
|
||||
AsExpression = 213,
|
||||
NonNullExpression = 214,
|
||||
MetaProperty = 215,
|
||||
SyntheticExpression = 216,
|
||||
TemplateSpan = 217,
|
||||
SemicolonClassElement = 218,
|
||||
Block = 219,
|
||||
VariableStatement = 220,
|
||||
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,
|
||||
ExpressionStatement = 222,
|
||||
IfStatement = 223,
|
||||
DoStatement = 224,
|
||||
WhileStatement = 225,
|
||||
ForStatement = 226,
|
||||
ForInStatement = 227,
|
||||
ForOfStatement = 228,
|
||||
ContinueStatement = 229,
|
||||
BreakStatement = 230,
|
||||
ReturnStatement = 231,
|
||||
WithStatement = 232,
|
||||
SwitchStatement = 233,
|
||||
LabeledStatement = 234,
|
||||
ThrowStatement = 235,
|
||||
TryStatement = 236,
|
||||
DebuggerStatement = 237,
|
||||
VariableDeclaration = 238,
|
||||
VariableDeclarationList = 239,
|
||||
FunctionDeclaration = 240,
|
||||
ClassDeclaration = 241,
|
||||
InterfaceDeclaration = 242,
|
||||
TypeAliasDeclaration = 243,
|
||||
EnumDeclaration = 244,
|
||||
ModuleDeclaration = 245,
|
||||
ModuleBlock = 246,
|
||||
CaseBlock = 247,
|
||||
NamespaceExportDeclaration = 248,
|
||||
ImportEqualsDeclaration = 249,
|
||||
ImportDeclaration = 250,
|
||||
ImportClause = 251,
|
||||
NamespaceImport = 252,
|
||||
NamedImports = 253,
|
||||
ImportSpecifier = 254,
|
||||
ExportAssignment = 255,
|
||||
ExportDeclaration = 256,
|
||||
NamedExports = 257,
|
||||
ExportSpecifier = 258,
|
||||
MissingDeclaration = 259,
|
||||
ExternalModuleReference = 260,
|
||||
JsxElement = 261,
|
||||
JsxSelfClosingElement = 262,
|
||||
JsxOpeningElement = 263,
|
||||
JsxClosingElement = 264,
|
||||
JsxFragment = 265,
|
||||
JsxOpeningFragment = 266,
|
||||
JsxClosingFragment = 267,
|
||||
JsxAttribute = 268,
|
||||
JsxAttributes = 269,
|
||||
JsxSpreadAttribute = 270,
|
||||
JsxExpression = 271,
|
||||
CaseClause = 272,
|
||||
DefaultClause = 273,
|
||||
HeritageClause = 274,
|
||||
CatchClause = 275,
|
||||
PropertyAssignment = 276,
|
||||
ShorthandPropertyAssignment = 277,
|
||||
SpreadAssignment = 278,
|
||||
EnumMember = 279,
|
||||
UnparsedPrologue = 280,
|
||||
UnparsedPrepend = 281,
|
||||
UnparsedText = 282,
|
||||
UnparsedInternalText = 283,
|
||||
UnparsedSyntheticReference = 284,
|
||||
SourceFile = 285,
|
||||
Bundle = 286,
|
||||
UnparsedSource = 287,
|
||||
InputFiles = 288,
|
||||
JSDocTypeExpression = 289,
|
||||
JSDocAllType = 290,
|
||||
JSDocUnknownType = 291,
|
||||
JSDocNullableType = 292,
|
||||
JSDocNonNullableType = 293,
|
||||
JSDocOptionalType = 294,
|
||||
JSDocFunctionType = 295,
|
||||
JSDocVariadicType = 296,
|
||||
JSDocNamepathType = 297,
|
||||
JSDocComment = 298,
|
||||
JSDocTypeLiteral = 299,
|
||||
JSDocSignature = 300,
|
||||
JSDocTag = 301,
|
||||
JSDocAugmentsTag = 302,
|
||||
JSDocAuthorTag = 303,
|
||||
JSDocClassTag = 304,
|
||||
JSDocCallbackTag = 305,
|
||||
JSDocEnumTag = 306,
|
||||
JSDocParameterTag = 307,
|
||||
JSDocReturnTag = 308,
|
||||
JSDocThisTag = 309,
|
||||
JSDocTypeTag = 310,
|
||||
JSDocTemplateTag = 311,
|
||||
JSDocTypedefTag = 312,
|
||||
JSDocPropertyTag = 313,
|
||||
SyntaxList = 314,
|
||||
NotEmittedStatement = 315,
|
||||
PartiallyEmittedExpression = 316,
|
||||
CommaListExpression = 317,
|
||||
MergeDeclarationMarker = 318,
|
||||
EndOfDeclarationMarker = 319,
|
||||
Count = 320,
|
||||
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,
|
||||
@@ -405,15 +406,15 @@ declare namespace ts {
|
||||
FirstReservedWord = 74,
|
||||
LastReservedWord = 109,
|
||||
FirstKeyword = 74,
|
||||
LastKeyword = 148,
|
||||
LastKeyword = 149,
|
||||
FirstFutureReservedWord = 110,
|
||||
LastFutureReservedWord = 118,
|
||||
FirstTypeNode = 164,
|
||||
LastTypeNode = 184,
|
||||
FirstTypeNode = 165,
|
||||
LastTypeNode = 185,
|
||||
FirstPunctuation = 18,
|
||||
LastPunctuation = 72,
|
||||
FirstToken = 0,
|
||||
LastToken = 148,
|
||||
LastToken = 149,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
@@ -422,11 +423,13 @@ declare namespace ts {
|
||||
LastTemplateToken = 17,
|
||||
FirstBinaryOperator = 28,
|
||||
LastBinaryOperator = 72,
|
||||
FirstNode = 149,
|
||||
FirstJSDocNode = 289,
|
||||
LastJSDocNode = 313,
|
||||
FirstJSDocTagNode = 301,
|
||||
LastJSDocTagNode = 313,
|
||||
FirstStatement = 222,
|
||||
LastStatement = 238,
|
||||
FirstNode = 150,
|
||||
FirstJSDocNode = 290,
|
||||
LastJSDocNode = 314,
|
||||
FirstJSDocTagNode = 302,
|
||||
LastJSDocTagNode = 314,
|
||||
}
|
||||
export enum NodeFlags {
|
||||
None = 0,
|
||||
@@ -517,6 +520,7 @@ declare namespace ts {
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
export type PlusToken = Token<SyntaxKind.PlusToken>;
|
||||
export type MinusToken = Token<SyntaxKind.MinusToken>;
|
||||
export type AssertsToken = Token<SyntaxKind.AssertsKeyword>;
|
||||
export type Modifier = Token<SyntaxKind.AbstractKeyword> | Token<SyntaxKind.AsyncKeyword> | Token<SyntaxKind.ConstKeyword> | Token<SyntaxKind.DeclareKeyword> | Token<SyntaxKind.DefaultKeyword> | Token<SyntaxKind.ExportKeyword> | Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword> | Token<SyntaxKind.ProtectedKeyword> | Token<SyntaxKind.ReadonlyKeyword> | Token<SyntaxKind.StaticKeyword>;
|
||||
export type ModifiersArray = NodeArray<Modifier>;
|
||||
export interface Identifier extends PrimaryExpression, Declaration {
|
||||
@@ -770,8 +774,9 @@ declare namespace ts {
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent: SignatureDeclaration | JSDocTypeExpression;
|
||||
assertsModifier?: AssertsToken;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
type?: TypeNode;
|
||||
}
|
||||
export interface TypeQueryNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeQuery;
|
||||
@@ -1669,13 +1674,19 @@ declare namespace ts {
|
||||
FalseCondition = 64,
|
||||
SwitchClause = 128,
|
||||
ArrayMutation = 256,
|
||||
Referenced = 512,
|
||||
Shared = 1024,
|
||||
PreFinally = 2048,
|
||||
AfterFinally = 4096,
|
||||
Call = 512,
|
||||
Referenced = 1024,
|
||||
Shared = 2048,
|
||||
PreFinally = 4096,
|
||||
AfterFinally = 8192,
|
||||
Label = 12,
|
||||
Condition = 96
|
||||
}
|
||||
export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
export interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
export interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
@@ -1686,13 +1697,8 @@ declare namespace ts {
|
||||
antecedent: FlowNode;
|
||||
lock: FlowLock;
|
||||
}
|
||||
export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation;
|
||||
export interface FlowNodeBase {
|
||||
flags: FlowFlags;
|
||||
id?: number;
|
||||
}
|
||||
export interface FlowStart extends FlowNodeBase {
|
||||
container?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
node?: FunctionExpression | ArrowFunction | MethodDeclaration;
|
||||
}
|
||||
export interface FlowLabel extends FlowNodeBase {
|
||||
antecedents: FlowNode[] | undefined;
|
||||
@@ -1701,8 +1707,12 @@ declare namespace ts {
|
||||
node: Expression | VariableDeclaration | BindingElement;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
export interface FlowCall extends FlowNodeBase {
|
||||
node: CallExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
export interface FlowCondition extends FlowNodeBase {
|
||||
expression: Expression;
|
||||
node: Expression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
export interface FlowSwitchClause extends FlowNodeBase {
|
||||
@@ -2098,21 +2108,39 @@ declare namespace ts {
|
||||
}
|
||||
export enum TypePredicateKind {
|
||||
This = 0,
|
||||
Identifier = 1
|
||||
Identifier = 1,
|
||||
AssertsThis = 2,
|
||||
AssertsIdentifier = 3
|
||||
}
|
||||
export interface TypePredicateBase {
|
||||
kind: TypePredicateKind;
|
||||
type: Type;
|
||||
type: Type | undefined;
|
||||
}
|
||||
export interface ThisTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.This;
|
||||
parameterName: undefined;
|
||||
parameterIndex: undefined;
|
||||
type: Type;
|
||||
}
|
||||
export interface IdentifierTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.Identifier;
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type;
|
||||
}
|
||||
export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate;
|
||||
export interface AssertsThisTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.AssertsThis;
|
||||
parameterName: undefined;
|
||||
parameterIndex: undefined;
|
||||
type: Type | undefined;
|
||||
}
|
||||
export interface AssertsIdentifierTypePredicate extends TypePredicateBase {
|
||||
kind: TypePredicateKind.AssertsIdentifier;
|
||||
parameterName: string;
|
||||
parameterIndex: number;
|
||||
type: Type | undefined;
|
||||
}
|
||||
export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate;
|
||||
export enum SymbolFlags {
|
||||
None = 0,
|
||||
FunctionScopedVariable = 1,
|
||||
@@ -3845,7 +3873,9 @@ declare namespace ts {
|
||||
function updateIndexSignature(node: IndexSignatureDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration;
|
||||
function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode;
|
||||
function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode;
|
||||
function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode;
|
||||
function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode;
|
||||
function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode;
|
||||
function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined): TypeReferenceNode;
|
||||
function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray<TypeNode> | undefined): TypeReferenceNode;
|
||||
function createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode;
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(116,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(117,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(118,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(121,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(122,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(123,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(124,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts (7 errors) ====
|
||||
declare function isString(value: unknown): value is string;
|
||||
declare function isArrayOfStrings(value: unknown): value is string[];
|
||||
|
||||
const assert: (value: unknown) => asserts value = value => {}
|
||||
|
||||
declare function assertIsString(value: unknown): asserts value is string;
|
||||
declare function assertIsArrayOfStrings(value: unknown): asserts value is string[];
|
||||
declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
|
||||
function f01(x: unknown) {
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x instanceof Error);
|
||||
x.message;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof x === "boolean" || typeof x === "number");
|
||||
x.toLocaleString;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(isArrayOfStrings(x));
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsArrayOfStrings(x);
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x === undefined || typeof x === "string");
|
||||
x; // string | undefined
|
||||
assertDefined(x);
|
||||
x; // string
|
||||
}
|
||||
}
|
||||
|
||||
function f02(x: string | undefined) {
|
||||
if (!!true) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
|
||||
function f03(x: string | undefined, assert: (value: unknown) => asserts value) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
export declare function assert(value: unknown, message?: string): asserts value;
|
||||
export declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
}
|
||||
|
||||
function f10(x: string | undefined) {
|
||||
if (!!true) {
|
||||
Debug.assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
assert(value: unknown): asserts value {
|
||||
if (value) return;
|
||||
throw new Error();
|
||||
}
|
||||
isTest2(): this is Test2 {
|
||||
return this instanceof Test2;
|
||||
}
|
||||
assertIsTest2(): asserts this is Test2 {
|
||||
if (this instanceof Test2) return;
|
||||
throw new Error();
|
||||
}
|
||||
assertThis(): asserts this {
|
||||
if (!this) return;
|
||||
throw new Error();
|
||||
}
|
||||
bar() {
|
||||
this.assertThis();
|
||||
this;
|
||||
}
|
||||
foo(x: unknown) {
|
||||
this.assert(typeof x === "string");
|
||||
x.length;
|
||||
if (this.isTest2()) {
|
||||
this.z;
|
||||
}
|
||||
this.assertIsTest2();
|
||||
this.z;
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 extends Test {
|
||||
z = 0;
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
|
||||
declare class Wat {
|
||||
get p1(): this is string;
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
set p1(x: this is string);
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
get p2(): asserts this is string;
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
set p2(x: asserts this is string);
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
//// [assertionTypePredicates1.ts]
|
||||
declare function isString(value: unknown): value is string;
|
||||
declare function isArrayOfStrings(value: unknown): value is string[];
|
||||
|
||||
const assert: (value: unknown) => asserts value = value => {}
|
||||
|
||||
declare function assertIsString(value: unknown): asserts value is string;
|
||||
declare function assertIsArrayOfStrings(value: unknown): asserts value is string[];
|
||||
declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
|
||||
function f01(x: unknown) {
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x instanceof Error);
|
||||
x.message;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof x === "boolean" || typeof x === "number");
|
||||
x.toLocaleString;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(isArrayOfStrings(x));
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsArrayOfStrings(x);
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x === undefined || typeof x === "string");
|
||||
x; // string | undefined
|
||||
assertDefined(x);
|
||||
x; // string
|
||||
}
|
||||
}
|
||||
|
||||
function f02(x: string | undefined) {
|
||||
if (!!true) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
|
||||
function f03(x: string | undefined, assert: (value: unknown) => asserts value) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
export declare function assert(value: unknown, message?: string): asserts value;
|
||||
export declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
}
|
||||
|
||||
function f10(x: string | undefined) {
|
||||
if (!!true) {
|
||||
Debug.assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
assert(value: unknown): asserts value {
|
||||
if (value) return;
|
||||
throw new Error();
|
||||
}
|
||||
isTest2(): this is Test2 {
|
||||
return this instanceof Test2;
|
||||
}
|
||||
assertIsTest2(): asserts this is Test2 {
|
||||
if (this instanceof Test2) return;
|
||||
throw new Error();
|
||||
}
|
||||
assertThis(): asserts this {
|
||||
if (!this) return;
|
||||
throw new Error();
|
||||
}
|
||||
bar() {
|
||||
this.assertThis();
|
||||
this;
|
||||
}
|
||||
foo(x: unknown) {
|
||||
this.assert(typeof x === "string");
|
||||
x.length;
|
||||
if (this.isTest2()) {
|
||||
this.z;
|
||||
}
|
||||
this.assertIsTest2();
|
||||
this.z;
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 extends Test {
|
||||
z = 0;
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
|
||||
declare class Wat {
|
||||
get p1(): this is string;
|
||||
set p1(x: this is string);
|
||||
get p2(): asserts this is string;
|
||||
set p2(x: asserts this is string);
|
||||
}
|
||||
|
||||
|
||||
//// [assertionTypePredicates1.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var assert = function (value) { };
|
||||
function f01(x) {
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x instanceof Error);
|
||||
x.message;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof x === "boolean" || typeof x === "number");
|
||||
x.toLocaleString;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(isArrayOfStrings(x));
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsArrayOfStrings(x);
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x === undefined || typeof x === "string");
|
||||
x; // string | undefined
|
||||
assertDefined(x);
|
||||
x; // string
|
||||
}
|
||||
}
|
||||
function f02(x) {
|
||||
if (!!true) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
function f03(x, assert) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
var Debug;
|
||||
(function (Debug) {
|
||||
})(Debug || (Debug = {}));
|
||||
function f10(x) {
|
||||
if (!!true) {
|
||||
Debug.assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
var Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
}
|
||||
Test.prototype.assert = function (value) {
|
||||
if (value)
|
||||
return;
|
||||
throw new Error();
|
||||
};
|
||||
Test.prototype.isTest2 = function () {
|
||||
return this instanceof Test2;
|
||||
};
|
||||
Test.prototype.assertIsTest2 = function () {
|
||||
if (this instanceof Test2)
|
||||
return;
|
||||
throw new Error();
|
||||
};
|
||||
Test.prototype.assertThis = function () {
|
||||
if (!this)
|
||||
return;
|
||||
throw new Error();
|
||||
};
|
||||
Test.prototype.bar = function () {
|
||||
this.assertThis();
|
||||
this;
|
||||
};
|
||||
Test.prototype.foo = function (x) {
|
||||
this.assert(typeof x === "string");
|
||||
x.length;
|
||||
if (this.isTest2()) {
|
||||
this.z;
|
||||
}
|
||||
this.assertIsTest2();
|
||||
this.z;
|
||||
};
|
||||
return Test;
|
||||
}());
|
||||
var Test2 = /** @class */ (function (_super) {
|
||||
__extends(Test2, _super);
|
||||
function Test2() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.z = 0;
|
||||
return _this;
|
||||
}
|
||||
return Test2;
|
||||
}(Test));
|
||||
|
||||
|
||||
//// [assertionTypePredicates1.d.ts]
|
||||
declare function isString(value: unknown): value is string;
|
||||
declare function isArrayOfStrings(value: unknown): value is string[];
|
||||
declare const assert: (value: unknown) => asserts value;
|
||||
declare function assertIsString(value: unknown): asserts value is string;
|
||||
declare function assertIsArrayOfStrings(value: unknown): asserts value is string[];
|
||||
declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
declare function f01(x: unknown): void;
|
||||
declare function f02(x: string | undefined): void;
|
||||
declare function f03(x: string | undefined, assert: (value: unknown) => asserts value): void;
|
||||
declare namespace Debug {
|
||||
function assert(value: unknown, message?: string): asserts value;
|
||||
function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
}
|
||||
declare function f10(x: string | undefined): void;
|
||||
declare class Test {
|
||||
assert(value: unknown): asserts value;
|
||||
isTest2(): this is Test2;
|
||||
assertIsTest2(): asserts this is Test2;
|
||||
assertThis(): asserts this;
|
||||
bar(): void;
|
||||
foo(x: unknown): void;
|
||||
}
|
||||
declare class Test2 extends Test {
|
||||
z: number;
|
||||
}
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
declare class Wat {
|
||||
get p1(): this is string;
|
||||
set p1(x: this is string);
|
||||
get p2(): asserts this is string;
|
||||
set p2(x: asserts this is string);
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
=== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts ===
|
||||
declare function isString(value: unknown): value is string;
|
||||
>isString : Symbol(isString, Decl(assertionTypePredicates1.ts, 0, 0))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 0, 26))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 0, 26))
|
||||
|
||||
declare function isArrayOfStrings(value: unknown): value is string[];
|
||||
>isArrayOfStrings : Symbol(isArrayOfStrings, Decl(assertionTypePredicates1.ts, 0, 59))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 1, 34))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 1, 34))
|
||||
|
||||
const assert: (value: unknown) => asserts value = value => {}
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 3, 15))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 3, 15))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 3, 49))
|
||||
|
||||
declare function assertIsString(value: unknown): asserts value is string;
|
||||
>assertIsString : Symbol(assertIsString, Decl(assertionTypePredicates1.ts, 3, 61))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 5, 32))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 5, 32))
|
||||
|
||||
declare function assertIsArrayOfStrings(value: unknown): asserts value is string[];
|
||||
>assertIsArrayOfStrings : Symbol(assertIsArrayOfStrings, Decl(assertionTypePredicates1.ts, 5, 73))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 6, 40))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 6, 40))
|
||||
|
||||
declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 6, 83))
|
||||
>T : Symbol(T, Decl(assertionTypePredicates1.ts, 7, 31))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 7, 34))
|
||||
>T : Symbol(T, Decl(assertionTypePredicates1.ts, 7, 31))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 7, 34))
|
||||
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(assertionTypePredicates1.ts, 7, 31))
|
||||
|
||||
function f01(x: unknown) {
|
||||
>f01 : Symbol(f01, Decl(assertionTypePredicates1.ts, 7, 77))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x instanceof Error);
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
x.message;
|
||||
>x.message : Symbol(Error.message, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>message : Symbol(Error.message, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof x === "boolean" || typeof x === "number");
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
x.toLocaleString;
|
||||
>x.toLocaleString : Symbol(toLocaleString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>toLocaleString : Symbol(toLocaleString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(isArrayOfStrings(x));
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>isArrayOfStrings : Symbol(isArrayOfStrings, Decl(assertionTypePredicates1.ts, 0, 59))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
x[0].length;
|
||||
>x[0].length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsArrayOfStrings(x);
|
||||
>assertIsArrayOfStrings : Symbol(assertIsArrayOfStrings, Decl(assertionTypePredicates1.ts, 5, 73))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
x[0].length;
|
||||
>x[0].length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x === undefined || typeof x === "string");
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
x; // string | undefined
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
assertDefined(x);
|
||||
>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 6, 83))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
|
||||
x; // string
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13))
|
||||
}
|
||||
}
|
||||
|
||||
function f02(x: string | undefined) {
|
||||
>f02 : Symbol(f02, Decl(assertionTypePredicates1.ts, 36, 1))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
|
||||
if (!!true) {
|
||||
assert(x);
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x !== undefined);
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assertDefined(x);
|
||||
>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 6, 83))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
function f03(x: string | undefined, assert: (value: unknown) => asserts value) {
|
||||
>f03 : Symbol(f03, Decl(assertionTypePredicates1.ts, 51, 1))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 53, 13))
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 53, 35))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 53, 45))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 53, 45))
|
||||
|
||||
assert(x);
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 53, 35))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 53, 13))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 53, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1))
|
||||
|
||||
export declare function assert(value: unknown, message?: string): asserts value;
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 58, 17))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 59, 35))
|
||||
>message : Symbol(message, Decl(assertionTypePredicates1.ts, 59, 50))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 59, 35))
|
||||
|
||||
export declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 59, 84))
|
||||
>T : Symbol(T, Decl(assertionTypePredicates1.ts, 60, 42))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 60, 45))
|
||||
>T : Symbol(T, Decl(assertionTypePredicates1.ts, 60, 42))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 60, 45))
|
||||
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(assertionTypePredicates1.ts, 60, 42))
|
||||
}
|
||||
|
||||
function f10(x: string | undefined) {
|
||||
>f10 : Symbol(f10, Decl(assertionTypePredicates1.ts, 61, 1))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
|
||||
if (!!true) {
|
||||
Debug.assert(x);
|
||||
>Debug.assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17))
|
||||
>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1))
|
||||
>assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assert(x !== undefined);
|
||||
>Debug.assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17))
|
||||
>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1))
|
||||
>assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assertDefined(x);
|
||||
>Debug.assertDefined : Symbol(Debug.assertDefined, Decl(assertionTypePredicates1.ts, 59, 84))
|
||||
>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1))
|
||||
>assertDefined : Symbol(Debug.assertDefined, Decl(assertionTypePredicates1.ts, 59, 84))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
|
||||
assert(value: unknown): asserts value {
|
||||
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 78, 12))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 79, 11))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 79, 11))
|
||||
|
||||
if (value) return;
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 79, 11))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
isTest2(): this is Test2 {
|
||||
>isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 82, 5))
|
||||
>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1))
|
||||
|
||||
return this instanceof Test2;
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1))
|
||||
}
|
||||
assertIsTest2(): asserts this is Test2 {
|
||||
>assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 85, 5))
|
||||
>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1))
|
||||
|
||||
if (this instanceof Test2) return;
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
assertThis(): asserts this {
|
||||
>assertThis : Symbol(Test.assertThis, Decl(assertionTypePredicates1.ts, 89, 5))
|
||||
|
||||
if (!this) return;
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
bar() {
|
||||
>bar : Symbol(Test.bar, Decl(assertionTypePredicates1.ts, 93, 5))
|
||||
|
||||
this.assertThis();
|
||||
>this.assertThis : Symbol(Test.assertThis, Decl(assertionTypePredicates1.ts, 89, 5))
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
>assertThis : Symbol(Test.assertThis, Decl(assertionTypePredicates1.ts, 89, 5))
|
||||
|
||||
this;
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
}
|
||||
foo(x: unknown) {
|
||||
>foo : Symbol(Test.foo, Decl(assertionTypePredicates1.ts, 97, 5))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 98, 8))
|
||||
|
||||
this.assert(typeof x === "string");
|
||||
>this.assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 78, 12))
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 78, 12))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 98, 8))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 98, 8))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
if (this.isTest2()) {
|
||||
>this.isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 82, 5))
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
>isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 82, 5))
|
||||
|
||||
this.z;
|
||||
>this.z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26))
|
||||
>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26))
|
||||
}
|
||||
this.assertIsTest2();
|
||||
>this.assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 85, 5))
|
||||
>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
>assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 85, 5))
|
||||
|
||||
this.z;
|
||||
>this.z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26))
|
||||
>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26))
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 extends Test {
|
||||
>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1))
|
||||
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1))
|
||||
|
||||
z = 0;
|
||||
>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26))
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
>Q1 : Symbol(Q1, Decl(assertionTypePredicates1.ts, 115, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 115, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 115, 21))
|
||||
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
>Q2 : Symbol(Q2, Decl(assertionTypePredicates1.ts, 116, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 116, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 116, 21))
|
||||
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
>Q3 : Symbol(Q3, Decl(assertionTypePredicates1.ts, 117, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 117, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 117, 21))
|
||||
|
||||
declare class Wat {
|
||||
>Wat : Symbol(Wat, Decl(assertionTypePredicates1.ts, 117, 56))
|
||||
|
||||
get p1(): this is string;
|
||||
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 119, 19), Decl(assertionTypePredicates1.ts, 120, 29))
|
||||
|
||||
set p1(x: this is string);
|
||||
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 119, 19), Decl(assertionTypePredicates1.ts, 120, 29))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 121, 11))
|
||||
|
||||
get p2(): asserts this is string;
|
||||
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 121, 30), Decl(assertionTypePredicates1.ts, 122, 37))
|
||||
|
||||
set p2(x: asserts this is string);
|
||||
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 121, 30), Decl(assertionTypePredicates1.ts, 122, 37))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 123, 11))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
=== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts ===
|
||||
declare function isString(value: unknown): value is string;
|
||||
>isString : (value: unknown) => value is string
|
||||
>value : unknown
|
||||
|
||||
declare function isArrayOfStrings(value: unknown): value is string[];
|
||||
>isArrayOfStrings : (value: unknown) => value is string[]
|
||||
>value : unknown
|
||||
|
||||
const assert: (value: unknown) => asserts value = value => {}
|
||||
>assert : (value: unknown) => asserts value
|
||||
>value : unknown
|
||||
>value => {} : (value: unknown) => void
|
||||
>value : unknown
|
||||
|
||||
declare function assertIsString(value: unknown): asserts value is string;
|
||||
>assertIsString : (value: unknown) => asserts value is string
|
||||
>value : unknown
|
||||
|
||||
declare function assertIsArrayOfStrings(value: unknown): asserts value is string[];
|
||||
>assertIsArrayOfStrings : (value: unknown) => asserts value is string[]
|
||||
>value : unknown
|
||||
|
||||
declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
>assertDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>value : T
|
||||
|
||||
function f01(x: unknown) {
|
||||
>f01 : (x: unknown) => void
|
||||
>x : unknown
|
||||
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(typeof x === "string");
|
||||
>assert(typeof x === "string") : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>"string" : "string"
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(x instanceof Error);
|
||||
>assert(x instanceof Error) : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>x instanceof Error : boolean
|
||||
>x : unknown
|
||||
>Error : ErrorConstructor
|
||||
|
||||
x.message;
|
||||
>x.message : string
|
||||
>x : Error
|
||||
>message : string
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(typeof x === "boolean" || typeof x === "number");
|
||||
>assert(typeof x === "boolean" || typeof x === "number") : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>typeof x === "boolean" || typeof x === "number" : boolean
|
||||
>typeof x === "boolean" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>"boolean" : "boolean"
|
||||
>typeof x === "number" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>"number" : "number"
|
||||
|
||||
x.toLocaleString;
|
||||
>x.toLocaleString : ((locales?: string | string[] | undefined, options?: Intl.NumberFormatOptions | undefined) => string) | (() => string)
|
||||
>x : number | boolean
|
||||
>toLocaleString : ((locales?: string | string[] | undefined, options?: Intl.NumberFormatOptions | undefined) => string) | (() => string)
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(isArrayOfStrings(x));
|
||||
>assert(isArrayOfStrings(x)) : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>isArrayOfStrings(x) : boolean
|
||||
>isArrayOfStrings : (value: unknown) => value is string[]
|
||||
>x : unknown
|
||||
|
||||
x[0].length;
|
||||
>x[0].length : number
|
||||
>x[0] : string
|
||||
>x : string[]
|
||||
>0 : 0
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assertIsArrayOfStrings(x);
|
||||
>assertIsArrayOfStrings(x) : void
|
||||
>assertIsArrayOfStrings : (value: unknown) => asserts value is string[]
|
||||
>x : unknown
|
||||
|
||||
x[0].length;
|
||||
>x[0].length : number
|
||||
>x[0] : string
|
||||
>x : string[]
|
||||
>0 : 0
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(x === undefined || typeof x === "string");
|
||||
>assert(x === undefined || typeof x === "string") : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>x === undefined || typeof x === "string" : boolean
|
||||
>x === undefined : boolean
|
||||
>x : unknown
|
||||
>undefined : undefined
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>"string" : "string"
|
||||
|
||||
x; // string | undefined
|
||||
>x : string | undefined
|
||||
|
||||
assertDefined(x);
|
||||
>assertDefined(x) : void
|
||||
>assertDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>x : string | undefined
|
||||
|
||||
x; // string
|
||||
>x : string
|
||||
}
|
||||
}
|
||||
|
||||
function f02(x: string | undefined) {
|
||||
>f02 : (x: string | undefined) => void
|
||||
>x : string | undefined
|
||||
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(x);
|
||||
>assert(x) : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>x : string | undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(x !== undefined);
|
||||
>assert(x !== undefined) : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>x !== undefined : boolean
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assertDefined(x);
|
||||
>assertDefined(x) : void
|
||||
>assertDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>x : string | undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
}
|
||||
|
||||
function f03(x: string | undefined, assert: (value: unknown) => asserts value) {
|
||||
>f03 : (x: string | undefined, assert: (value: unknown) => asserts value) => void
|
||||
>x : string | undefined
|
||||
>assert : (value: unknown) => asserts value
|
||||
>value : unknown
|
||||
|
||||
assert(x);
|
||||
>assert(x) : void
|
||||
>assert : (value: unknown) => asserts value
|
||||
>x : string | undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
>Debug : typeof Debug
|
||||
|
||||
export declare function assert(value: unknown, message?: string): asserts value;
|
||||
>assert : (value: unknown, message?: string | undefined) => asserts value
|
||||
>value : unknown
|
||||
>message : string | undefined
|
||||
|
||||
export declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
>assertDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>value : T
|
||||
}
|
||||
|
||||
function f10(x: string | undefined) {
|
||||
>f10 : (x: string | undefined) => void
|
||||
>x : string | undefined
|
||||
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
Debug.assert(x);
|
||||
>Debug.assert(x) : void
|
||||
>Debug.assert : (value: unknown, message?: string | undefined) => asserts value
|
||||
>Debug : typeof Debug
|
||||
>assert : (value: unknown, message?: string | undefined) => asserts value
|
||||
>x : string | undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
Debug.assert(x !== undefined);
|
||||
>Debug.assert(x !== undefined) : void
|
||||
>Debug.assert : (value: unknown, message?: string | undefined) => asserts value
|
||||
>Debug : typeof Debug
|
||||
>assert : (value: unknown, message?: string | undefined) => asserts value
|
||||
>x !== undefined : boolean
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
Debug.assertDefined(x);
|
||||
>Debug.assertDefined(x) : void
|
||||
>Debug.assertDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>Debug : typeof Debug
|
||||
>assertDefined : <T>(value: T) => asserts value is NonNullable<T>
|
||||
>x : string | undefined
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
assert(value: unknown): asserts value {
|
||||
>assert : (value: unknown) => asserts value
|
||||
>value : unknown
|
||||
|
||||
if (value) return;
|
||||
>value : unknown
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
isTest2(): this is Test2 {
|
||||
>isTest2 : () => this is Test2
|
||||
|
||||
return this instanceof Test2;
|
||||
>this instanceof Test2 : boolean
|
||||
>this : this
|
||||
>Test2 : typeof Test2
|
||||
}
|
||||
assertIsTest2(): asserts this is Test2 {
|
||||
>assertIsTest2 : () => asserts this is Test2
|
||||
|
||||
if (this instanceof Test2) return;
|
||||
>this instanceof Test2 : boolean
|
||||
>this : this
|
||||
>Test2 : typeof Test2
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
assertThis(): asserts this {
|
||||
>assertThis : () => asserts this
|
||||
|
||||
if (!this) return;
|
||||
>!this : false
|
||||
>this : this
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
bar() {
|
||||
>bar : () => void
|
||||
|
||||
this.assertThis();
|
||||
>this.assertThis() : void
|
||||
>this.assertThis : () => asserts this
|
||||
>this : this
|
||||
>assertThis : () => asserts this
|
||||
|
||||
this;
|
||||
>this : this
|
||||
}
|
||||
foo(x: unknown) {
|
||||
>foo : (x: unknown) => void
|
||||
>x : unknown
|
||||
|
||||
this.assert(typeof x === "string");
|
||||
>this.assert(typeof x === "string") : void
|
||||
>this.assert : (value: unknown) => asserts value
|
||||
>this : this
|
||||
>assert : (value: unknown) => asserts value
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>"string" : "string"
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
|
||||
if (this.isTest2()) {
|
||||
>this.isTest2() : boolean
|
||||
>this.isTest2 : () => this is Test2
|
||||
>this : this
|
||||
>isTest2 : () => this is Test2
|
||||
|
||||
this.z;
|
||||
>this.z : number
|
||||
>this : this & Test2
|
||||
>z : number
|
||||
}
|
||||
this.assertIsTest2();
|
||||
>this.assertIsTest2() : void
|
||||
>this.assertIsTest2 : () => asserts this is Test2
|
||||
>this : this
|
||||
>assertIsTest2 : () => asserts this is Test2
|
||||
|
||||
this.z;
|
||||
>this.z : number
|
||||
>this : this & Test2
|
||||
>z : number
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 extends Test {
|
||||
>Test2 : Test2
|
||||
>Test : Test
|
||||
|
||||
z = 0;
|
||||
>z : number
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
>Q1 : new (x: unknown) => x is string
|
||||
>x : unknown
|
||||
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
>Q2 : new (x: boolean) => asserts x
|
||||
>x : boolean
|
||||
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
>Q3 : new (x: unknown) => asserts x is string
|
||||
>x : unknown
|
||||
|
||||
declare class Wat {
|
||||
>Wat : Wat
|
||||
|
||||
get p1(): this is string;
|
||||
>p1 : boolean
|
||||
|
||||
set p1(x: this is string);
|
||||
>p1 : boolean
|
||||
>x : boolean
|
||||
|
||||
get p2(): asserts this is string;
|
||||
>p2 : void
|
||||
|
||||
set p2(x: asserts this is string);
|
||||
>p2 : void
|
||||
>x : void
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js(46,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js(58,5): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js (2 errors) ====
|
||||
/** @typedef {(check: boolean) => asserts check} AssertFunc */
|
||||
|
||||
/** @type {AssertFunc} */
|
||||
const assert = check => {
|
||||
if (!check) throw new Error();
|
||||
}
|
||||
|
||||
/** @type {(x: unknown) => asserts x is string } */
|
||||
function assertIsString(x) {
|
||||
if (!(typeof x === "string")) throw new Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} check
|
||||
* @returns {asserts check}
|
||||
*/
|
||||
function assert2(check) {
|
||||
if (!check) throw new Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {never}
|
||||
*/
|
||||
function fail() {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} x
|
||||
*/
|
||||
function f1(x) {
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert2(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsString(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} b
|
||||
*/
|
||||
function f2(b) {
|
||||
switch (b) {
|
||||
case true: return 1;
|
||||
case false: return 0;
|
||||
}
|
||||
b; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
=== tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js ===
|
||||
/** @typedef {(check: boolean) => asserts check} AssertFunc */
|
||||
|
||||
/** @type {AssertFunc} */
|
||||
const assert = check => {
|
||||
>assert : Symbol(assert, Decl(assertionsAndNonReturningFunctions.js, 3, 5))
|
||||
>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 3, 14))
|
||||
|
||||
if (!check) throw new Error();
|
||||
>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 3, 14))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
/** @type {(x: unknown) => asserts x is string } */
|
||||
function assertIsString(x) {
|
||||
>assertIsString : Symbol(assertIsString, Decl(assertionsAndNonReturningFunctions.js, 5, 1))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 8, 24))
|
||||
|
||||
if (!(typeof x === "string")) throw new Error();
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 8, 24))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} check
|
||||
* @returns {asserts check}
|
||||
*/
|
||||
function assert2(check) {
|
||||
>assert2 : Symbol(assert2, Decl(assertionsAndNonReturningFunctions.js, 10, 1))
|
||||
>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 16, 17))
|
||||
|
||||
if (!check) throw new Error();
|
||||
>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 16, 17))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {never}
|
||||
*/
|
||||
function fail() {
|
||||
>fail : Symbol(fail, Decl(assertionsAndNonReturningFunctions.js, 18, 1))
|
||||
|
||||
throw new Error();
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} x
|
||||
*/
|
||||
function f1(x) {
|
||||
>f1 : Symbol(f1, Decl(assertionsAndNonReturningFunctions.js, 25, 1))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
>assert : Symbol(assert, Decl(assertionsAndNonReturningFunctions.js, 3, 5))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assert2(typeof x === "string");
|
||||
>assert2 : Symbol(assert2, Decl(assertionsAndNonReturningFunctions.js, 10, 1))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsString(x);
|
||||
>assertIsString : Symbol(assertIsString, Decl(assertionsAndNonReturningFunctions.js, 5, 1))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
|
||||
x.length;
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
if (!!true) {
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(assertionsAndNonReturningFunctions.js, 18, 1))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} b
|
||||
*/
|
||||
function f2(b) {
|
||||
>f2 : Symbol(f2, Decl(assertionsAndNonReturningFunctions.js, 47, 1))
|
||||
>b : Symbol(b, Decl(assertionsAndNonReturningFunctions.js, 52, 12))
|
||||
|
||||
switch (b) {
|
||||
>b : Symbol(b, Decl(assertionsAndNonReturningFunctions.js, 52, 12))
|
||||
|
||||
case true: return 1;
|
||||
case false: return 0;
|
||||
}
|
||||
b; // Unreachable
|
||||
>b : Symbol(b, Decl(assertionsAndNonReturningFunctions.js, 52, 12))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
=== tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js ===
|
||||
/** @typedef {(check: boolean) => asserts check} AssertFunc */
|
||||
|
||||
/** @type {AssertFunc} */
|
||||
const assert = check => {
|
||||
>assert : (check: boolean) => asserts check
|
||||
>check => { if (!check) throw new Error();} : (check: boolean) => asserts check
|
||||
>check : boolean
|
||||
|
||||
if (!check) throw new Error();
|
||||
>!check : boolean
|
||||
>check : boolean
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
/** @type {(x: unknown) => asserts x is string } */
|
||||
function assertIsString(x) {
|
||||
>assertIsString : (x: unknown) => asserts x is string
|
||||
>x : unknown
|
||||
|
||||
if (!(typeof x === "string")) throw new Error();
|
||||
>!(typeof x === "string") : boolean
|
||||
>(typeof x === "string") : boolean
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : unknown
|
||||
>"string" : "string"
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} check
|
||||
* @returns {asserts check}
|
||||
*/
|
||||
function assert2(check) {
|
||||
>assert2 : (check: boolean) => asserts check
|
||||
>check : boolean
|
||||
|
||||
if (!check) throw new Error();
|
||||
>!check : boolean
|
||||
>check : boolean
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {never}
|
||||
*/
|
||||
function fail() {
|
||||
>fail : () => never
|
||||
|
||||
throw new Error();
|
||||
>new Error() : Error
|
||||
>Error : ErrorConstructor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} x
|
||||
*/
|
||||
function f1(x) {
|
||||
>f1 : (x: any) => void
|
||||
>x : any
|
||||
|
||||
if (!!true) {
|
||||
>!!true : boolean
|
||||
>!true : boolean
|
||||
>true : true
|
||||
|
||||
assert(typeof x === "string");
|
||||
>assert(typeof x === "string") : void
|
||||
>assert : (check: boolean) => asserts check
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : any
|
||||
>"string" : "string"
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : boolean
|
||||
>!true : boolean
|
||||
>true : true
|
||||
|
||||
assert2(typeof x === "string");
|
||||
>assert2(typeof x === "string") : void
|
||||
>assert2 : (check: boolean) => asserts check
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : any
|
||||
>"string" : "string"
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : boolean
|
||||
>!true : boolean
|
||||
>true : true
|
||||
|
||||
assertIsString(x);
|
||||
>assertIsString(x) : void
|
||||
>assertIsString : (x: unknown) => asserts x is string
|
||||
>x : any
|
||||
|
||||
x.length;
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : boolean
|
||||
>!true : boolean
|
||||
>true : true
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : () => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} b
|
||||
*/
|
||||
function f2(b) {
|
||||
>f2 : (b: boolean) => 1 | 0
|
||||
>b : boolean
|
||||
|
||||
switch (b) {
|
||||
>b : boolean
|
||||
|
||||
case true: return 1;
|
||||
>true : true
|
||||
>1 : 1
|
||||
|
||||
case false: return 0;
|
||||
>false : false
|
||||
>0 : 0
|
||||
}
|
||||
b; // Unreachable
|
||||
>b : never
|
||||
}
|
||||
|
||||
@@ -44,4 +44,18 @@ tests/cases/compiler/exhaustiveSwitchImplicitReturn.ts(35,32): error TS7030: Not
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function foo6(bar: "a", a: boolean, b: boolean): number {
|
||||
if (a) {
|
||||
switch (bar) {
|
||||
case "a": return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (b) {
|
||||
case true: return -1;
|
||||
case false: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,20 @@ function foo5(bar: "a" | "b"): number {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function foo6(bar: "a", a: boolean, b: boolean): number {
|
||||
if (a) {
|
||||
switch (bar) {
|
||||
case "a": return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (b) {
|
||||
case true: return -1;
|
||||
case false: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [exhaustiveSwitchImplicitReturn.js]
|
||||
@@ -75,3 +89,16 @@ function foo5(bar) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
function foo6(bar, a, b) {
|
||||
if (a) {
|
||||
switch (bar) {
|
||||
case "a": return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (b) {
|
||||
case true: return -1;
|
||||
case false: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,3 +69,28 @@ function foo5(bar: "a" | "b"): number {
|
||||
}
|
||||
}
|
||||
|
||||
function foo6(bar: "a", a: boolean, b: boolean): number {
|
||||
>foo6 : Symbol(foo6, Decl(exhaustiveSwitchImplicitReturn.ts, 39, 1))
|
||||
>bar : Symbol(bar, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 14))
|
||||
>a : Symbol(a, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 23))
|
||||
>b : Symbol(b, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 35))
|
||||
|
||||
if (a) {
|
||||
>a : Symbol(a, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 23))
|
||||
|
||||
switch (bar) {
|
||||
>bar : Symbol(bar, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 14))
|
||||
|
||||
case "a": return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (b) {
|
||||
>b : Symbol(b, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 35))
|
||||
|
||||
case true: return -1;
|
||||
case false: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,3 +85,36 @@ function foo5(bar: "a" | "b"): number {
|
||||
}
|
||||
}
|
||||
|
||||
function foo6(bar: "a", a: boolean, b: boolean): number {
|
||||
>foo6 : (bar: "a", a: boolean, b: boolean) => number
|
||||
>bar : "a"
|
||||
>a : boolean
|
||||
>b : boolean
|
||||
|
||||
if (a) {
|
||||
>a : boolean
|
||||
|
||||
switch (bar) {
|
||||
>bar : "a"
|
||||
|
||||
case "a": return 1;
|
||||
>"a" : "a"
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (b) {
|
||||
>b : boolean
|
||||
|
||||
case true: return -1;
|
||||
>true : true
|
||||
>-1 : -1
|
||||
>1 : 1
|
||||
|
||||
case false: return 0;
|
||||
>false : false
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(7,9): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts (1 errors) ====
|
||||
function f1(x: 1 | 2): string {
|
||||
if (!!true) {
|
||||
switch (x) {
|
||||
case 1: return 'a';
|
||||
case 2: return 'b';
|
||||
}
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
else {
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: 1 | 2) {
|
||||
let z: number;
|
||||
switch (x) {
|
||||
case 1: z = 10; break;
|
||||
case 2: z = 20; break;
|
||||
}
|
||||
z; // Definitely assigned
|
||||
}
|
||||
|
||||
function f3(x: 1 | 2) {
|
||||
switch (x) {
|
||||
case 1: return 10;
|
||||
case 2: return 20;
|
||||
// Default considered reachable to allow defensive coding
|
||||
default: throw new Error("Bad input");
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #11572
|
||||
|
||||
enum E { A, B }
|
||||
|
||||
function f(e: E): number {
|
||||
switch (e) {
|
||||
case E.A: return 0
|
||||
case E.B: return 1
|
||||
}
|
||||
}
|
||||
|
||||
function g(e: E): number {
|
||||
if (!true)
|
||||
return -1
|
||||
else
|
||||
switch (e) {
|
||||
case E.A: return 0
|
||||
case E.B: return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #12668
|
||||
|
||||
interface Square { kind: "square"; size: number; }
|
||||
|
||||
interface Rectangle { kind: "rectangle"; width: number; height: number; }
|
||||
|
||||
interface Circle { kind: "circle"; radius: number; }
|
||||
|
||||
interface Triangle { kind: "triangle"; side: number; }
|
||||
|
||||
type Shape = Square | Rectangle | Circle | Triangle;
|
||||
|
||||
function area(s: Shape): number {
|
||||
let area;
|
||||
switch (s.kind) {
|
||||
case "square": area = s.size * s.size; break;
|
||||
case "rectangle": area = s.width * s.height; break;
|
||||
case "circle": area = Math.PI * s.radius * s.radius; break;
|
||||
case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
function areaWrapped(s: Shape): number {
|
||||
let area;
|
||||
area = (() => {
|
||||
switch (s.kind) {
|
||||
case "square": return s.size * s.size;
|
||||
case "rectangle": return s.width * s.height;
|
||||
case "circle": return Math.PI * s.radius * s.radius;
|
||||
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
|
||||
}
|
||||
})();
|
||||
return area;
|
||||
}
|
||||
|
||||
// Repro from #13241
|
||||
|
||||
enum MyEnum {
|
||||
A,
|
||||
B
|
||||
}
|
||||
|
||||
function thisGivesError(e: MyEnum): string {
|
||||
let s: string;
|
||||
switch (e) {
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function good1(e: MyEnum): string {
|
||||
let s: string;
|
||||
switch (e) {
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
default: s = "it was something else"; break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function good2(e: MyEnum): string {
|
||||
switch (e) {
|
||||
case MyEnum.A: return "it was A";
|
||||
case MyEnum.B: return "it was B";
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #18362
|
||||
|
||||
enum Level {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
const doSomethingWithLevel = (level: Level) => {
|
||||
let next: Level;
|
||||
switch (level) {
|
||||
case Level.One:
|
||||
next = Level.Two;
|
||||
break;
|
||||
case Level.Two:
|
||||
next = Level.One;
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
};
|
||||
|
||||
// Repro from #20409
|
||||
|
||||
interface Square2 {
|
||||
kind: "square";
|
||||
size: number;
|
||||
}
|
||||
|
||||
interface Circle2 {
|
||||
kind: "circle";
|
||||
radius: number;
|
||||
}
|
||||
|
||||
type Shape2 = Square2 | Circle2;
|
||||
|
||||
function withDefault(s1: Shape2, s2: Shape2): string {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
default:
|
||||
return "never";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function withoutDefault(s1: Shape2, s2: Shape2): string {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #20823
|
||||
|
||||
function test4(value: 1 | 2) {
|
||||
let x: string;
|
||||
switch (value) {
|
||||
case 1: x = "one"; break;
|
||||
case 2: x = "two"; break;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
//// [exhaustiveSwitchStatements1.ts]
|
||||
function f1(x: 1 | 2): string {
|
||||
if (!!true) {
|
||||
switch (x) {
|
||||
case 1: return 'a';
|
||||
case 2: return 'b';
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: 1 | 2) {
|
||||
let z: number;
|
||||
switch (x) {
|
||||
case 1: z = 10; break;
|
||||
case 2: z = 20; break;
|
||||
}
|
||||
z; // Definitely assigned
|
||||
}
|
||||
|
||||
function f3(x: 1 | 2) {
|
||||
switch (x) {
|
||||
case 1: return 10;
|
||||
case 2: return 20;
|
||||
// Default considered reachable to allow defensive coding
|
||||
default: throw new Error("Bad input");
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #11572
|
||||
|
||||
enum E { A, B }
|
||||
|
||||
function f(e: E): number {
|
||||
switch (e) {
|
||||
case E.A: return 0
|
||||
case E.B: return 1
|
||||
}
|
||||
}
|
||||
|
||||
function g(e: E): number {
|
||||
if (!true)
|
||||
return -1
|
||||
else
|
||||
switch (e) {
|
||||
case E.A: return 0
|
||||
case E.B: return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #12668
|
||||
|
||||
interface Square { kind: "square"; size: number; }
|
||||
|
||||
interface Rectangle { kind: "rectangle"; width: number; height: number; }
|
||||
|
||||
interface Circle { kind: "circle"; radius: number; }
|
||||
|
||||
interface Triangle { kind: "triangle"; side: number; }
|
||||
|
||||
type Shape = Square | Rectangle | Circle | Triangle;
|
||||
|
||||
function area(s: Shape): number {
|
||||
let area;
|
||||
switch (s.kind) {
|
||||
case "square": area = s.size * s.size; break;
|
||||
case "rectangle": area = s.width * s.height; break;
|
||||
case "circle": area = Math.PI * s.radius * s.radius; break;
|
||||
case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
function areaWrapped(s: Shape): number {
|
||||
let area;
|
||||
area = (() => {
|
||||
switch (s.kind) {
|
||||
case "square": return s.size * s.size;
|
||||
case "rectangle": return s.width * s.height;
|
||||
case "circle": return Math.PI * s.radius * s.radius;
|
||||
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
|
||||
}
|
||||
})();
|
||||
return area;
|
||||
}
|
||||
|
||||
// Repro from #13241
|
||||
|
||||
enum MyEnum {
|
||||
A,
|
||||
B
|
||||
}
|
||||
|
||||
function thisGivesError(e: MyEnum): string {
|
||||
let s: string;
|
||||
switch (e) {
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function good1(e: MyEnum): string {
|
||||
let s: string;
|
||||
switch (e) {
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
default: s = "it was something else"; break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function good2(e: MyEnum): string {
|
||||
switch (e) {
|
||||
case MyEnum.A: return "it was A";
|
||||
case MyEnum.B: return "it was B";
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #18362
|
||||
|
||||
enum Level {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
const doSomethingWithLevel = (level: Level) => {
|
||||
let next: Level;
|
||||
switch (level) {
|
||||
case Level.One:
|
||||
next = Level.Two;
|
||||
break;
|
||||
case Level.Two:
|
||||
next = Level.One;
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
};
|
||||
|
||||
// Repro from #20409
|
||||
|
||||
interface Square2 {
|
||||
kind: "square";
|
||||
size: number;
|
||||
}
|
||||
|
||||
interface Circle2 {
|
||||
kind: "circle";
|
||||
radius: number;
|
||||
}
|
||||
|
||||
type Shape2 = Square2 | Circle2;
|
||||
|
||||
function withDefault(s1: Shape2, s2: Shape2): string {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
default:
|
||||
return "never";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function withoutDefault(s1: Shape2, s2: Shape2): string {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #20823
|
||||
|
||||
function test4(value: 1 | 2) {
|
||||
let x: string;
|
||||
switch (value) {
|
||||
case 1: x = "one"; break;
|
||||
case 2: x = "two"; break;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
//// [exhaustiveSwitchStatements1.js]
|
||||
"use strict";
|
||||
function f1(x) {
|
||||
if (!!true) {
|
||||
switch (x) {
|
||||
case 1: return 'a';
|
||||
case 2: return 'b';
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
function f2(x) {
|
||||
var z;
|
||||
switch (x) {
|
||||
case 1:
|
||||
z = 10;
|
||||
break;
|
||||
case 2:
|
||||
z = 20;
|
||||
break;
|
||||
}
|
||||
z; // Definitely assigned
|
||||
}
|
||||
function f3(x) {
|
||||
switch (x) {
|
||||
case 1: return 10;
|
||||
case 2: return 20;
|
||||
// Default considered reachable to allow defensive coding
|
||||
default: throw new Error("Bad input");
|
||||
}
|
||||
}
|
||||
// Repro from #11572
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
E[E["B"] = 1] = "B";
|
||||
})(E || (E = {}));
|
||||
function f(e) {
|
||||
switch (e) {
|
||||
case E.A: return 0;
|
||||
case E.B: return 1;
|
||||
}
|
||||
}
|
||||
function g(e) {
|
||||
if (!true)
|
||||
return -1;
|
||||
else
|
||||
switch (e) {
|
||||
case E.A: return 0;
|
||||
case E.B: return 1;
|
||||
}
|
||||
}
|
||||
function area(s) {
|
||||
var area;
|
||||
switch (s.kind) {
|
||||
case "square":
|
||||
area = s.size * s.size;
|
||||
break;
|
||||
case "rectangle":
|
||||
area = s.width * s.height;
|
||||
break;
|
||||
case "circle":
|
||||
area = Math.PI * s.radius * s.radius;
|
||||
break;
|
||||
case "triangle":
|
||||
area = Math.sqrt(3) / 4 * s.side * s.side;
|
||||
break;
|
||||
}
|
||||
return area;
|
||||
}
|
||||
function areaWrapped(s) {
|
||||
var area;
|
||||
area = (function () {
|
||||
switch (s.kind) {
|
||||
case "square": return s.size * s.size;
|
||||
case "rectangle": return s.width * s.height;
|
||||
case "circle": return Math.PI * s.radius * s.radius;
|
||||
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
|
||||
}
|
||||
})();
|
||||
return area;
|
||||
}
|
||||
// Repro from #13241
|
||||
var MyEnum;
|
||||
(function (MyEnum) {
|
||||
MyEnum[MyEnum["A"] = 0] = "A";
|
||||
MyEnum[MyEnum["B"] = 1] = "B";
|
||||
})(MyEnum || (MyEnum = {}));
|
||||
function thisGivesError(e) {
|
||||
var s;
|
||||
switch (e) {
|
||||
case MyEnum.A:
|
||||
s = "it was A";
|
||||
break;
|
||||
case MyEnum.B:
|
||||
s = "it was B";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
function good1(e) {
|
||||
var s;
|
||||
switch (e) {
|
||||
case MyEnum.A:
|
||||
s = "it was A";
|
||||
break;
|
||||
case MyEnum.B:
|
||||
s = "it was B";
|
||||
break;
|
||||
default:
|
||||
s = "it was something else";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
function good2(e) {
|
||||
switch (e) {
|
||||
case MyEnum.A: return "it was A";
|
||||
case MyEnum.B: return "it was B";
|
||||
}
|
||||
}
|
||||
// Repro from #18362
|
||||
var Level;
|
||||
(function (Level) {
|
||||
Level[Level["One"] = 0] = "One";
|
||||
Level[Level["Two"] = 1] = "Two";
|
||||
})(Level || (Level = {}));
|
||||
var doSomethingWithLevel = function (level) {
|
||||
var next;
|
||||
switch (level) {
|
||||
case Level.One:
|
||||
next = Level.Two;
|
||||
break;
|
||||
case Level.Two:
|
||||
next = Level.One;
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
};
|
||||
function withDefault(s1, s2) {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
default:
|
||||
return "never";
|
||||
}
|
||||
}
|
||||
}
|
||||
function withoutDefault(s1, s2) {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Repro from #20823
|
||||
function test4(value) {
|
||||
var x;
|
||||
switch (value) {
|
||||
case 1:
|
||||
x = "one";
|
||||
break;
|
||||
case 2:
|
||||
x = "two";
|
||||
break;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
//// [exhaustiveSwitchStatements1.d.ts]
|
||||
declare function f1(x: 1 | 2): string;
|
||||
declare function f2(x: 1 | 2): void;
|
||||
declare function f3(x: 1 | 2): 10 | 20;
|
||||
declare enum E {
|
||||
A = 0,
|
||||
B = 1
|
||||
}
|
||||
declare function f(e: E): number;
|
||||
declare function g(e: E): number;
|
||||
interface Square {
|
||||
kind: "square";
|
||||
size: number;
|
||||
}
|
||||
interface Rectangle {
|
||||
kind: "rectangle";
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
interface Circle {
|
||||
kind: "circle";
|
||||
radius: number;
|
||||
}
|
||||
interface Triangle {
|
||||
kind: "triangle";
|
||||
side: number;
|
||||
}
|
||||
declare type Shape = Square | Rectangle | Circle | Triangle;
|
||||
declare function area(s: Shape): number;
|
||||
declare function areaWrapped(s: Shape): number;
|
||||
declare enum MyEnum {
|
||||
A = 0,
|
||||
B = 1
|
||||
}
|
||||
declare function thisGivesError(e: MyEnum): string;
|
||||
declare function good1(e: MyEnum): string;
|
||||
declare function good2(e: MyEnum): string;
|
||||
declare enum Level {
|
||||
One = 0,
|
||||
Two = 1
|
||||
}
|
||||
declare const doSomethingWithLevel: (level: Level) => Level;
|
||||
interface Square2 {
|
||||
kind: "square";
|
||||
size: number;
|
||||
}
|
||||
interface Circle2 {
|
||||
kind: "circle";
|
||||
radius: number;
|
||||
}
|
||||
declare type Shape2 = Square2 | Circle2;
|
||||
declare function withDefault(s1: Shape2, s2: Shape2): string;
|
||||
declare function withoutDefault(s1: Shape2, s2: Shape2): string;
|
||||
declare function test4(value: 1 | 2): string;
|
||||
@@ -0,0 +1,503 @@
|
||||
=== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts ===
|
||||
function f1(x: 1 | 2): string {
|
||||
>f1 : Symbol(f1, Decl(exhaustiveSwitchStatements1.ts, 0, 0))
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 0, 12))
|
||||
|
||||
if (!!true) {
|
||||
switch (x) {
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 0, 12))
|
||||
|
||||
case 1: return 'a';
|
||||
case 2: return 'b';
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 0, 12))
|
||||
}
|
||||
else {
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: 1 | 2) {
|
||||
>f2 : Symbol(f2, Decl(exhaustiveSwitchStatements1.ts, 11, 1))
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 13, 12))
|
||||
|
||||
let z: number;
|
||||
>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7))
|
||||
|
||||
switch (x) {
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 13, 12))
|
||||
|
||||
case 1: z = 10; break;
|
||||
>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7))
|
||||
|
||||
case 2: z = 20; break;
|
||||
>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7))
|
||||
}
|
||||
z; // Definitely assigned
|
||||
>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7))
|
||||
}
|
||||
|
||||
function f3(x: 1 | 2) {
|
||||
>f3 : Symbol(f3, Decl(exhaustiveSwitchStatements1.ts, 20, 1))
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 22, 12))
|
||||
|
||||
switch (x) {
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 22, 12))
|
||||
|
||||
case 1: return 10;
|
||||
case 2: return 20;
|
||||
// Default considered reachable to allow defensive coding
|
||||
default: throw new Error("Bad input");
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #11572
|
||||
|
||||
enum E { A, B }
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
>A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8))
|
||||
>B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11))
|
||||
|
||||
function f(e: E): number {
|
||||
>f : Symbol(f, Decl(exhaustiveSwitchStatements1.ts, 33, 15))
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 35, 11))
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
|
||||
switch (e) {
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 35, 11))
|
||||
|
||||
case E.A: return 0
|
||||
>E.A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8))
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
>A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8))
|
||||
|
||||
case E.B: return 1
|
||||
>E.B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11))
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
>B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11))
|
||||
}
|
||||
}
|
||||
|
||||
function g(e: E): number {
|
||||
>g : Symbol(g, Decl(exhaustiveSwitchStatements1.ts, 40, 1))
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 42, 11))
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
|
||||
if (!true)
|
||||
return -1
|
||||
else
|
||||
switch (e) {
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 42, 11))
|
||||
|
||||
case E.A: return 0
|
||||
>E.A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8))
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
>A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8))
|
||||
|
||||
case E.B: return 1
|
||||
>E.B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11))
|
||||
>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1))
|
||||
>B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #12668
|
||||
|
||||
interface Square { kind: "square"; size: number; }
|
||||
>Square : Symbol(Square, Decl(exhaustiveSwitchStatements1.ts, 50, 1))
|
||||
>kind : Symbol(Square.kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18))
|
||||
>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
|
||||
interface Rectangle { kind: "rectangle"; width: number; height: number; }
|
||||
>Rectangle : Symbol(Rectangle, Decl(exhaustiveSwitchStatements1.ts, 54, 50))
|
||||
>kind : Symbol(Rectangle.kind, Decl(exhaustiveSwitchStatements1.ts, 56, 21))
|
||||
>width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40))
|
||||
>height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55))
|
||||
|
||||
interface Circle { kind: "circle"; radius: number; }
|
||||
>Circle : Symbol(Circle, Decl(exhaustiveSwitchStatements1.ts, 56, 73))
|
||||
>kind : Symbol(Circle.kind, Decl(exhaustiveSwitchStatements1.ts, 58, 18))
|
||||
>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
|
||||
interface Triangle { kind: "triangle"; side: number; }
|
||||
>Triangle : Symbol(Triangle, Decl(exhaustiveSwitchStatements1.ts, 58, 52))
|
||||
>kind : Symbol(Triangle.kind, Decl(exhaustiveSwitchStatements1.ts, 60, 20))
|
||||
>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
|
||||
type Shape = Square | Rectangle | Circle | Triangle;
|
||||
>Shape : Symbol(Shape, Decl(exhaustiveSwitchStatements1.ts, 60, 54))
|
||||
>Square : Symbol(Square, Decl(exhaustiveSwitchStatements1.ts, 50, 1))
|
||||
>Rectangle : Symbol(Rectangle, Decl(exhaustiveSwitchStatements1.ts, 54, 50))
|
||||
>Circle : Symbol(Circle, Decl(exhaustiveSwitchStatements1.ts, 56, 73))
|
||||
>Triangle : Symbol(Triangle, Decl(exhaustiveSwitchStatements1.ts, 58, 52))
|
||||
|
||||
function area(s: Shape): number {
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 62, 52))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>Shape : Symbol(Shape, Decl(exhaustiveSwitchStatements1.ts, 60, 54))
|
||||
|
||||
let area;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7))
|
||||
|
||||
switch (s.kind) {
|
||||
>s.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20))
|
||||
|
||||
case "square": area = s.size * s.size; break;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7))
|
||||
>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
|
||||
case "rectangle": area = s.width * s.height; break;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7))
|
||||
>s.width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40))
|
||||
>s.height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55))
|
||||
|
||||
case "circle": area = Math.PI * s.radius * s.radius; break;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7))
|
||||
>Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --))
|
||||
>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
|
||||
case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7))
|
||||
>Math.sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --))
|
||||
>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14))
|
||||
>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
}
|
||||
return area;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7))
|
||||
}
|
||||
|
||||
function areaWrapped(s: Shape): number {
|
||||
>areaWrapped : Symbol(areaWrapped, Decl(exhaustiveSwitchStatements1.ts, 73, 1))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>Shape : Symbol(Shape, Decl(exhaustiveSwitchStatements1.ts, 60, 54))
|
||||
|
||||
let area;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 76, 7))
|
||||
|
||||
area = (() => {
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 76, 7))
|
||||
|
||||
switch (s.kind) {
|
||||
>s.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20))
|
||||
|
||||
case "square": return s.size * s.size;
|
||||
>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34))
|
||||
|
||||
case "rectangle": return s.width * s.height;
|
||||
>s.width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40))
|
||||
>s.height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55))
|
||||
|
||||
case "circle": return Math.PI * s.radius * s.radius;
|
||||
>Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --))
|
||||
>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34))
|
||||
|
||||
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
|
||||
>Math.sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --))
|
||||
>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21))
|
||||
>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38))
|
||||
}
|
||||
})();
|
||||
return area;
|
||||
>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 76, 7))
|
||||
}
|
||||
|
||||
// Repro from #13241
|
||||
|
||||
enum MyEnum {
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
|
||||
A,
|
||||
>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
|
||||
B
|
||||
>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
}
|
||||
|
||||
function thisGivesError(e: MyEnum): string {
|
||||
>thisGivesError : Symbol(thisGivesError, Decl(exhaustiveSwitchStatements1.ts, 93, 1))
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 95, 24))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
|
||||
let s: string;
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4))
|
||||
|
||||
switch (e) {
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 95, 24))
|
||||
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
>MyEnum.A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4))
|
||||
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
>MyEnum.B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4))
|
||||
}
|
||||
return s;
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4))
|
||||
}
|
||||
|
||||
function good1(e: MyEnum): string {
|
||||
>good1 : Symbol(good1, Decl(exhaustiveSwitchStatements1.ts, 102, 1))
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 104, 15))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
|
||||
let s: string;
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4))
|
||||
|
||||
switch (e) {
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 104, 15))
|
||||
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
>MyEnum.A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4))
|
||||
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
>MyEnum.B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4))
|
||||
|
||||
default: s = "it was something else"; break;
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4))
|
||||
}
|
||||
return s;
|
||||
>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4))
|
||||
}
|
||||
|
||||
function good2(e: MyEnum): string {
|
||||
>good2 : Symbol(good2, Decl(exhaustiveSwitchStatements1.ts, 112, 1))
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 114, 15))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
|
||||
switch (e) {
|
||||
>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 114, 15))
|
||||
|
||||
case MyEnum.A: return "it was A";
|
||||
>MyEnum.A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13))
|
||||
|
||||
case MyEnum.B: return "it was B";
|
||||
>MyEnum.B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1))
|
||||
>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #18362
|
||||
|
||||
enum Level {
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
|
||||
One,
|
||||
>One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12))
|
||||
|
||||
Two,
|
||||
>Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6))
|
||||
}
|
||||
|
||||
const doSomethingWithLevel = (level: Level) => {
|
||||
>doSomethingWithLevel : Symbol(doSomethingWithLevel, Decl(exhaustiveSwitchStatements1.ts, 128, 5))
|
||||
>level : Symbol(level, Decl(exhaustiveSwitchStatements1.ts, 128, 30))
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
|
||||
let next: Level;
|
||||
>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5))
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
|
||||
switch (level) {
|
||||
>level : Symbol(level, Decl(exhaustiveSwitchStatements1.ts, 128, 30))
|
||||
|
||||
case Level.One:
|
||||
>Level.One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12))
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
>One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12))
|
||||
|
||||
next = Level.Two;
|
||||
>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5))
|
||||
>Level.Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6))
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
>Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6))
|
||||
|
||||
break;
|
||||
case Level.Two:
|
||||
>Level.Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6))
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
>Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6))
|
||||
|
||||
next = Level.One;
|
||||
>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5))
|
||||
>Level.One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12))
|
||||
>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1))
|
||||
>One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12))
|
||||
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5))
|
||||
|
||||
};
|
||||
|
||||
// Repro from #20409
|
||||
|
||||
interface Square2 {
|
||||
>Square2 : Symbol(Square2, Decl(exhaustiveSwitchStatements1.ts, 139, 2))
|
||||
|
||||
kind: "square";
|
||||
>kind : Symbol(Square2.kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19))
|
||||
|
||||
size: number;
|
||||
>size : Symbol(Square2.size, Decl(exhaustiveSwitchStatements1.ts, 144, 19))
|
||||
}
|
||||
|
||||
interface Circle2 {
|
||||
>Circle2 : Symbol(Circle2, Decl(exhaustiveSwitchStatements1.ts, 146, 1))
|
||||
|
||||
kind: "circle";
|
||||
>kind : Symbol(Circle2.kind, Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
|
||||
radius: number;
|
||||
>radius : Symbol(Circle2.radius, Decl(exhaustiveSwitchStatements1.ts, 149, 19))
|
||||
}
|
||||
|
||||
type Shape2 = Square2 | Circle2;
|
||||
>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1))
|
||||
>Square2 : Symbol(Square2, Decl(exhaustiveSwitchStatements1.ts, 139, 2))
|
||||
>Circle2 : Symbol(Circle2, Decl(exhaustiveSwitchStatements1.ts, 146, 1))
|
||||
|
||||
function withDefault(s1: Shape2, s2: Shape2): string {
|
||||
>withDefault : Symbol(withDefault, Decl(exhaustiveSwitchStatements1.ts, 153, 32))
|
||||
>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 155, 21))
|
||||
>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1))
|
||||
>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 155, 32))
|
||||
>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1))
|
||||
|
||||
switch (s1.kind) {
|
||||
>s1.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 155, 21))
|
||||
>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
>s2.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 155, 32))
|
||||
>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
default:
|
||||
return "never";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function withoutDefault(s1: Shape2, s2: Shape2): string {
|
||||
>withoutDefault : Symbol(withoutDefault, Decl(exhaustiveSwitchStatements1.ts, 169, 1))
|
||||
>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 171, 24))
|
||||
>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1))
|
||||
>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 171, 35))
|
||||
>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1))
|
||||
|
||||
switch (s1.kind) {
|
||||
>s1.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 171, 24))
|
||||
>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
>s2.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 171, 35))
|
||||
>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19))
|
||||
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #20823
|
||||
|
||||
function test4(value: 1 | 2) {
|
||||
>test4 : Symbol(test4, Decl(exhaustiveSwitchStatements1.ts, 183, 1))
|
||||
>value : Symbol(value, Decl(exhaustiveSwitchStatements1.ts, 187, 15))
|
||||
|
||||
let x: string;
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7))
|
||||
|
||||
switch (value) {
|
||||
>value : Symbol(value, Decl(exhaustiveSwitchStatements1.ts, 187, 15))
|
||||
|
||||
case 1: x = "one"; break;
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7))
|
||||
|
||||
case 2: x = "two"; break;
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7))
|
||||
}
|
||||
return x;
|
||||
>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,595 @@
|
||||
=== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts ===
|
||||
function f1(x: 1 | 2): string {
|
||||
>f1 : (x: 1 | 2) => string
|
||||
>x : 1 | 2
|
||||
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
switch (x) {
|
||||
>x : 1 | 2
|
||||
|
||||
case 1: return 'a';
|
||||
>1 : 1
|
||||
>'a' : "a"
|
||||
|
||||
case 2: return 'b';
|
||||
>2 : 2
|
||||
>'b' : "b"
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : never
|
||||
}
|
||||
else {
|
||||
throw 0;
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: 1 | 2) {
|
||||
>f2 : (x: 1 | 2) => void
|
||||
>x : 1 | 2
|
||||
|
||||
let z: number;
|
||||
>z : number
|
||||
|
||||
switch (x) {
|
||||
>x : 1 | 2
|
||||
|
||||
case 1: z = 10; break;
|
||||
>1 : 1
|
||||
>z = 10 : 10
|
||||
>z : number
|
||||
>10 : 10
|
||||
|
||||
case 2: z = 20; break;
|
||||
>2 : 2
|
||||
>z = 20 : 20
|
||||
>z : number
|
||||
>20 : 20
|
||||
}
|
||||
z; // Definitely assigned
|
||||
>z : number
|
||||
}
|
||||
|
||||
function f3(x: 1 | 2) {
|
||||
>f3 : (x: 1 | 2) => 10 | 20
|
||||
>x : 1 | 2
|
||||
|
||||
switch (x) {
|
||||
>x : 1 | 2
|
||||
|
||||
case 1: return 10;
|
||||
>1 : 1
|
||||
>10 : 10
|
||||
|
||||
case 2: return 20;
|
||||
>2 : 2
|
||||
>20 : 20
|
||||
|
||||
// Default considered reachable to allow defensive coding
|
||||
default: throw new Error("Bad input");
|
||||
>new Error("Bad input") : Error
|
||||
>Error : ErrorConstructor
|
||||
>"Bad input" : "Bad input"
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #11572
|
||||
|
||||
enum E { A, B }
|
||||
>E : E
|
||||
>A : E.A
|
||||
>B : E.B
|
||||
|
||||
function f(e: E): number {
|
||||
>f : (e: E) => number
|
||||
>e : E
|
||||
|
||||
switch (e) {
|
||||
>e : E
|
||||
|
||||
case E.A: return 0
|
||||
>E.A : E.A
|
||||
>E : typeof E
|
||||
>A : E.A
|
||||
>0 : 0
|
||||
|
||||
case E.B: return 1
|
||||
>E.B : E.B
|
||||
>E : typeof E
|
||||
>B : E.B
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
function g(e: E): number {
|
||||
>g : (e: E) => number
|
||||
>e : E
|
||||
|
||||
if (!true)
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
return -1
|
||||
>-1 : -1
|
||||
>1 : 1
|
||||
|
||||
else
|
||||
switch (e) {
|
||||
>e : E
|
||||
|
||||
case E.A: return 0
|
||||
>E.A : E.A
|
||||
>E : typeof E
|
||||
>A : E.A
|
||||
>0 : 0
|
||||
|
||||
case E.B: return 1
|
||||
>E.B : E.B
|
||||
>E : typeof E
|
||||
>B : E.B
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #12668
|
||||
|
||||
interface Square { kind: "square"; size: number; }
|
||||
>kind : "square"
|
||||
>size : number
|
||||
|
||||
interface Rectangle { kind: "rectangle"; width: number; height: number; }
|
||||
>kind : "rectangle"
|
||||
>width : number
|
||||
>height : number
|
||||
|
||||
interface Circle { kind: "circle"; radius: number; }
|
||||
>kind : "circle"
|
||||
>radius : number
|
||||
|
||||
interface Triangle { kind: "triangle"; side: number; }
|
||||
>kind : "triangle"
|
||||
>side : number
|
||||
|
||||
type Shape = Square | Rectangle | Circle | Triangle;
|
||||
>Shape : Shape
|
||||
|
||||
function area(s: Shape): number {
|
||||
>area : (s: Shape) => number
|
||||
>s : Shape
|
||||
|
||||
let area;
|
||||
>area : any
|
||||
|
||||
switch (s.kind) {
|
||||
>s.kind : "square" | "rectangle" | "circle" | "triangle"
|
||||
>s : Shape
|
||||
>kind : "square" | "rectangle" | "circle" | "triangle"
|
||||
|
||||
case "square": area = s.size * s.size; break;
|
||||
>"square" : "square"
|
||||
>area = s.size * s.size : number
|
||||
>area : any
|
||||
>s.size * s.size : number
|
||||
>s.size : number
|
||||
>s : Square
|
||||
>size : number
|
||||
>s.size : number
|
||||
>s : Square
|
||||
>size : number
|
||||
|
||||
case "rectangle": area = s.width * s.height; break;
|
||||
>"rectangle" : "rectangle"
|
||||
>area = s.width * s.height : number
|
||||
>area : any
|
||||
>s.width * s.height : number
|
||||
>s.width : number
|
||||
>s : Rectangle
|
||||
>width : number
|
||||
>s.height : number
|
||||
>s : Rectangle
|
||||
>height : number
|
||||
|
||||
case "circle": area = Math.PI * s.radius * s.radius; break;
|
||||
>"circle" : "circle"
|
||||
>area = Math.PI * s.radius * s.radius : number
|
||||
>area : any
|
||||
>Math.PI * s.radius * s.radius : number
|
||||
>Math.PI * s.radius : number
|
||||
>Math.PI : number
|
||||
>Math : Math
|
||||
>PI : number
|
||||
>s.radius : number
|
||||
>s : Circle
|
||||
>radius : number
|
||||
>s.radius : number
|
||||
>s : Circle
|
||||
>radius : number
|
||||
|
||||
case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
|
||||
>"triangle" : "triangle"
|
||||
>area = Math.sqrt(3) / 4 * s.side * s.side : number
|
||||
>area : any
|
||||
>Math.sqrt(3) / 4 * s.side * s.side : number
|
||||
>Math.sqrt(3) / 4 * s.side : number
|
||||
>Math.sqrt(3) / 4 : number
|
||||
>Math.sqrt(3) : number
|
||||
>Math.sqrt : (x: number) => number
|
||||
>Math : Math
|
||||
>sqrt : (x: number) => number
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
>s.side : number
|
||||
>s : Triangle
|
||||
>side : number
|
||||
>s.side : number
|
||||
>s : Triangle
|
||||
>side : number
|
||||
}
|
||||
return area;
|
||||
>area : number
|
||||
}
|
||||
|
||||
function areaWrapped(s: Shape): number {
|
||||
>areaWrapped : (s: Shape) => number
|
||||
>s : Shape
|
||||
|
||||
let area;
|
||||
>area : any
|
||||
|
||||
area = (() => {
|
||||
>area = (() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } })() : number
|
||||
>area : any
|
||||
>(() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } })() : number
|
||||
>(() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } }) : () => number
|
||||
>() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } } : () => number
|
||||
|
||||
switch (s.kind) {
|
||||
>s.kind : "square" | "rectangle" | "circle" | "triangle"
|
||||
>s : Shape
|
||||
>kind : "square" | "rectangle" | "circle" | "triangle"
|
||||
|
||||
case "square": return s.size * s.size;
|
||||
>"square" : "square"
|
||||
>s.size * s.size : number
|
||||
>s.size : number
|
||||
>s : Square
|
||||
>size : number
|
||||
>s.size : number
|
||||
>s : Square
|
||||
>size : number
|
||||
|
||||
case "rectangle": return s.width * s.height;
|
||||
>"rectangle" : "rectangle"
|
||||
>s.width * s.height : number
|
||||
>s.width : number
|
||||
>s : Rectangle
|
||||
>width : number
|
||||
>s.height : number
|
||||
>s : Rectangle
|
||||
>height : number
|
||||
|
||||
case "circle": return Math.PI * s.radius * s.radius;
|
||||
>"circle" : "circle"
|
||||
>Math.PI * s.radius * s.radius : number
|
||||
>Math.PI * s.radius : number
|
||||
>Math.PI : number
|
||||
>Math : Math
|
||||
>PI : number
|
||||
>s.radius : number
|
||||
>s : Circle
|
||||
>radius : number
|
||||
>s.radius : number
|
||||
>s : Circle
|
||||
>radius : number
|
||||
|
||||
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
|
||||
>"triangle" : "triangle"
|
||||
>Math.sqrt(3) / 4 * s.side * s.side : number
|
||||
>Math.sqrt(3) / 4 * s.side : number
|
||||
>Math.sqrt(3) / 4 : number
|
||||
>Math.sqrt(3) : number
|
||||
>Math.sqrt : (x: number) => number
|
||||
>Math : Math
|
||||
>sqrt : (x: number) => number
|
||||
>3 : 3
|
||||
>4 : 4
|
||||
>s.side : number
|
||||
>s : Triangle
|
||||
>side : number
|
||||
>s.side : number
|
||||
>s : Triangle
|
||||
>side : number
|
||||
}
|
||||
})();
|
||||
return area;
|
||||
>area : number
|
||||
}
|
||||
|
||||
// Repro from #13241
|
||||
|
||||
enum MyEnum {
|
||||
>MyEnum : MyEnum
|
||||
|
||||
A,
|
||||
>A : MyEnum.A
|
||||
|
||||
B
|
||||
>B : MyEnum.B
|
||||
}
|
||||
|
||||
function thisGivesError(e: MyEnum): string {
|
||||
>thisGivesError : (e: MyEnum) => string
|
||||
>e : MyEnum
|
||||
|
||||
let s: string;
|
||||
>s : string
|
||||
|
||||
switch (e) {
|
||||
>e : MyEnum
|
||||
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
>MyEnum.A : MyEnum.A
|
||||
>MyEnum : typeof MyEnum
|
||||
>A : MyEnum.A
|
||||
>s = "it was A" : "it was A"
|
||||
>s : string
|
||||
>"it was A" : "it was A"
|
||||
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
>MyEnum.B : MyEnum.B
|
||||
>MyEnum : typeof MyEnum
|
||||
>B : MyEnum.B
|
||||
>s = "it was B" : "it was B"
|
||||
>s : string
|
||||
>"it was B" : "it was B"
|
||||
}
|
||||
return s;
|
||||
>s : string
|
||||
}
|
||||
|
||||
function good1(e: MyEnum): string {
|
||||
>good1 : (e: MyEnum) => string
|
||||
>e : MyEnum
|
||||
|
||||
let s: string;
|
||||
>s : string
|
||||
|
||||
switch (e) {
|
||||
>e : MyEnum
|
||||
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
>MyEnum.A : MyEnum.A
|
||||
>MyEnum : typeof MyEnum
|
||||
>A : MyEnum.A
|
||||
>s = "it was A" : "it was A"
|
||||
>s : string
|
||||
>"it was A" : "it was A"
|
||||
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
>MyEnum.B : MyEnum.B
|
||||
>MyEnum : typeof MyEnum
|
||||
>B : MyEnum.B
|
||||
>s = "it was B" : "it was B"
|
||||
>s : string
|
||||
>"it was B" : "it was B"
|
||||
|
||||
default: s = "it was something else"; break;
|
||||
>s = "it was something else" : "it was something else"
|
||||
>s : string
|
||||
>"it was something else" : "it was something else"
|
||||
}
|
||||
return s;
|
||||
>s : string
|
||||
}
|
||||
|
||||
function good2(e: MyEnum): string {
|
||||
>good2 : (e: MyEnum) => string
|
||||
>e : MyEnum
|
||||
|
||||
switch (e) {
|
||||
>e : MyEnum
|
||||
|
||||
case MyEnum.A: return "it was A";
|
||||
>MyEnum.A : MyEnum.A
|
||||
>MyEnum : typeof MyEnum
|
||||
>A : MyEnum.A
|
||||
>"it was A" : "it was A"
|
||||
|
||||
case MyEnum.B: return "it was B";
|
||||
>MyEnum.B : MyEnum.B
|
||||
>MyEnum : typeof MyEnum
|
||||
>B : MyEnum.B
|
||||
>"it was B" : "it was B"
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #18362
|
||||
|
||||
enum Level {
|
||||
>Level : Level
|
||||
|
||||
One,
|
||||
>One : Level.One
|
||||
|
||||
Two,
|
||||
>Two : Level.Two
|
||||
}
|
||||
|
||||
const doSomethingWithLevel = (level: Level) => {
|
||||
>doSomethingWithLevel : (level: Level) => Level
|
||||
>(level: Level) => { let next: Level; switch (level) { case Level.One: next = Level.Two; break; case Level.Two: next = Level.One; break; } return next;} : (level: Level) => Level
|
||||
>level : Level
|
||||
|
||||
let next: Level;
|
||||
>next : Level
|
||||
|
||||
switch (level) {
|
||||
>level : Level
|
||||
|
||||
case Level.One:
|
||||
>Level.One : Level.One
|
||||
>Level : typeof Level
|
||||
>One : Level.One
|
||||
|
||||
next = Level.Two;
|
||||
>next = Level.Two : Level.Two
|
||||
>next : Level
|
||||
>Level.Two : Level.Two
|
||||
>Level : typeof Level
|
||||
>Two : Level.Two
|
||||
|
||||
break;
|
||||
case Level.Two:
|
||||
>Level.Two : Level.Two
|
||||
>Level : typeof Level
|
||||
>Two : Level.Two
|
||||
|
||||
next = Level.One;
|
||||
>next = Level.One : Level.One
|
||||
>next : Level
|
||||
>Level.One : Level.One
|
||||
>Level : typeof Level
|
||||
>One : Level.One
|
||||
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
>next : Level
|
||||
|
||||
};
|
||||
|
||||
// Repro from #20409
|
||||
|
||||
interface Square2 {
|
||||
kind: "square";
|
||||
>kind : "square"
|
||||
|
||||
size: number;
|
||||
>size : number
|
||||
}
|
||||
|
||||
interface Circle2 {
|
||||
kind: "circle";
|
||||
>kind : "circle"
|
||||
|
||||
radius: number;
|
||||
>radius : number
|
||||
}
|
||||
|
||||
type Shape2 = Square2 | Circle2;
|
||||
>Shape2 : Shape2
|
||||
|
||||
function withDefault(s1: Shape2, s2: Shape2): string {
|
||||
>withDefault : (s1: Shape2, s2: Shape2) => string
|
||||
>s1 : Shape2
|
||||
>s2 : Shape2
|
||||
|
||||
switch (s1.kind) {
|
||||
>s1.kind : "square" | "circle"
|
||||
>s1 : Shape2
|
||||
>kind : "square" | "circle"
|
||||
|
||||
case "square":
|
||||
>"square" : "square"
|
||||
|
||||
return "1";
|
||||
>"1" : "1"
|
||||
|
||||
case "circle":
|
||||
>"circle" : "circle"
|
||||
|
||||
switch (s2.kind) {
|
||||
>s2.kind : "square" | "circle"
|
||||
>s2 : Shape2
|
||||
>kind : "square" | "circle"
|
||||
|
||||
case "square":
|
||||
>"square" : "square"
|
||||
|
||||
return "2";
|
||||
>"2" : "2"
|
||||
|
||||
case "circle":
|
||||
>"circle" : "circle"
|
||||
|
||||
return "3";
|
||||
>"3" : "3"
|
||||
|
||||
default:
|
||||
return "never";
|
||||
>"never" : "never"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function withoutDefault(s1: Shape2, s2: Shape2): string {
|
||||
>withoutDefault : (s1: Shape2, s2: Shape2) => string
|
||||
>s1 : Shape2
|
||||
>s2 : Shape2
|
||||
|
||||
switch (s1.kind) {
|
||||
>s1.kind : "square" | "circle"
|
||||
>s1 : Shape2
|
||||
>kind : "square" | "circle"
|
||||
|
||||
case "square":
|
||||
>"square" : "square"
|
||||
|
||||
return "1";
|
||||
>"1" : "1"
|
||||
|
||||
case "circle":
|
||||
>"circle" : "circle"
|
||||
|
||||
switch (s2.kind) {
|
||||
>s2.kind : "square" | "circle"
|
||||
>s2 : Shape2
|
||||
>kind : "square" | "circle"
|
||||
|
||||
case "square":
|
||||
>"square" : "square"
|
||||
|
||||
return "2";
|
||||
>"2" : "2"
|
||||
|
||||
case "circle":
|
||||
>"circle" : "circle"
|
||||
|
||||
return "3";
|
||||
>"3" : "3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #20823
|
||||
|
||||
function test4(value: 1 | 2) {
|
||||
>test4 : (value: 1 | 2) => string
|
||||
>value : 1 | 2
|
||||
|
||||
let x: string;
|
||||
>x : string
|
||||
|
||||
switch (value) {
|
||||
>value : 1 | 2
|
||||
|
||||
case 1: x = "one"; break;
|
||||
>1 : 1
|
||||
>x = "one" : "one"
|
||||
>x : string
|
||||
>"one" : "one"
|
||||
|
||||
case 2: x = "two"; break;
|
||||
>2 : 2
|
||||
>x = "two" : "two"
|
||||
>x : string
|
||||
>"two" : "two"
|
||||
}
|
||||
return x;
|
||||
>x : string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(13,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(19,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(30,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(36,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(51,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(57,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(63,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(77,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(82,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(89,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(96,13): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(101,13): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(103,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(105,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(111,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(112,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(122,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(127,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(129,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(139,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(141,5): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(148,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(153,5): error TS7027: Unreachable code detected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/neverReturningFunctions1.ts (23 errors) ====
|
||||
function fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function f01(x: string | undefined) {
|
||||
if (x === undefined) fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f02(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f03(x: string) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f11(x: string | undefined, fail: (message?: string) => never) {
|
||||
if (x === undefined) fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f12(x: number, fail: (message?: string) => never): number {
|
||||
if (x >= 0) return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f13(x: string, fail: (message?: string) => never) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
export declare function fail(message?: string): never;
|
||||
}
|
||||
|
||||
function f21(x: string | undefined) {
|
||||
if (x === undefined) Debug.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f22(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
Debug.fail("negative number");
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f23(x: string) {
|
||||
x; // string
|
||||
Debug.fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f24(x: string) {
|
||||
x; // string
|
||||
((Debug).fail)();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
class Test {
|
||||
fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
f1(x: string | undefined) {
|
||||
if (x === undefined) this.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
f2(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
this.fail("negative number");
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
f3(x: string) {
|
||||
x; // string
|
||||
this.fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
}
|
||||
|
||||
function f30(x: string | number | undefined) {
|
||||
if (typeof x === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
else {
|
||||
x; // number | undefined
|
||||
if (x !== undefined) {
|
||||
x; // number
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
else {
|
||||
x; // undefined
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f31(x: { a: string | number }) {
|
||||
if (typeof x.a === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
x.a; // Unreachable
|
||||
~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
x; // { a: string | number }
|
||||
x.a; // number
|
||||
}
|
||||
|
||||
function f40(x: number) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f41(x: number) {
|
||||
try {
|
||||
x;
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
function f42(x: number) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
}
|
||||
x; // Unreachable
|
||||
~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
//// [neverReturningFunctions1.ts]
|
||||
function fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function f01(x: string | undefined) {
|
||||
if (x === undefined) fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f02(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f03(x: string) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f11(x: string | undefined, fail: (message?: string) => never) {
|
||||
if (x === undefined) fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f12(x: number, fail: (message?: string) => never): number {
|
||||
if (x >= 0) return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f13(x: string, fail: (message?: string) => never) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
export declare function fail(message?: string): never;
|
||||
}
|
||||
|
||||
function f21(x: string | undefined) {
|
||||
if (x === undefined) Debug.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f22(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
Debug.fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f23(x: string) {
|
||||
x; // string
|
||||
Debug.fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f24(x: string) {
|
||||
x; // string
|
||||
((Debug).fail)();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
class Test {
|
||||
fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
f1(x: string | undefined) {
|
||||
if (x === undefined) this.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
f2(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
this.fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
f3(x: string) {
|
||||
x; // string
|
||||
this.fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
}
|
||||
|
||||
function f30(x: string | number | undefined) {
|
||||
if (typeof x === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
x; // number | undefined
|
||||
if (x !== undefined) {
|
||||
x; // number
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
x; // undefined
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f31(x: { a: string | number }) {
|
||||
if (typeof x.a === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
x.a; // Unreachable
|
||||
}
|
||||
x; // { a: string | number }
|
||||
x.a; // number
|
||||
}
|
||||
|
||||
function f40(x: number) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f41(x: number) {
|
||||
try {
|
||||
x;
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f42(x: number) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
|
||||
//// [neverReturningFunctions1.js]
|
||||
"use strict";
|
||||
function fail(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
function f01(x) {
|
||||
if (x === undefined)
|
||||
fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
function f02(x) {
|
||||
if (x >= 0)
|
||||
return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
function f03(x) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
function f11(x, fail) {
|
||||
if (x === undefined)
|
||||
fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
function f12(x, fail) {
|
||||
if (x >= 0)
|
||||
return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
function f13(x, fail) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
var Debug;
|
||||
(function (Debug) {
|
||||
})(Debug || (Debug = {}));
|
||||
function f21(x) {
|
||||
if (x === undefined)
|
||||
Debug.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
function f22(x) {
|
||||
if (x >= 0)
|
||||
return x;
|
||||
Debug.fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
function f23(x) {
|
||||
x; // string
|
||||
Debug.fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
function f24(x) {
|
||||
x; // string
|
||||
((Debug).fail)();
|
||||
x; // Unreachable
|
||||
}
|
||||
var Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
}
|
||||
Test.prototype.fail = function (message) {
|
||||
throw new Error(message);
|
||||
};
|
||||
Test.prototype.f1 = function (x) {
|
||||
if (x === undefined)
|
||||
this.fail("undefined argument");
|
||||
x.length; // string
|
||||
};
|
||||
Test.prototype.f2 = function (x) {
|
||||
if (x >= 0)
|
||||
return x;
|
||||
this.fail("negative number");
|
||||
x; // Unreachable
|
||||
};
|
||||
Test.prototype.f3 = function (x) {
|
||||
x; // string
|
||||
this.fail();
|
||||
x; // Unreachable
|
||||
};
|
||||
return Test;
|
||||
}());
|
||||
function f30(x) {
|
||||
if (typeof x === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
x; // number | undefined
|
||||
if (x !== undefined) {
|
||||
x; // number
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
x; // undefined
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
function f31(x) {
|
||||
if (typeof x.a === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
x.a; // Unreachable
|
||||
}
|
||||
x; // { a: string | number }
|
||||
x.a; // number
|
||||
}
|
||||
function f40(x) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
function f41(x) {
|
||||
try {
|
||||
x;
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
function f42(x) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
|
||||
//// [neverReturningFunctions1.d.ts]
|
||||
declare function fail(message?: string): never;
|
||||
declare function f01(x: string | undefined): void;
|
||||
declare function f02(x: number): number;
|
||||
declare function f03(x: string): void;
|
||||
declare function f11(x: string | undefined, fail: (message?: string) => never): void;
|
||||
declare function f12(x: number, fail: (message?: string) => never): number;
|
||||
declare function f13(x: string, fail: (message?: string) => never): void;
|
||||
declare namespace Debug {
|
||||
function fail(message?: string): never;
|
||||
}
|
||||
declare function f21(x: string | undefined): void;
|
||||
declare function f22(x: number): number;
|
||||
declare function f23(x: string): void;
|
||||
declare function f24(x: string): void;
|
||||
declare class Test {
|
||||
fail(message?: string): never;
|
||||
f1(x: string | undefined): void;
|
||||
f2(x: number): number;
|
||||
f3(x: string): void;
|
||||
}
|
||||
declare function f30(x: string | number | undefined): void;
|
||||
declare function f31(x: {
|
||||
a: string | number;
|
||||
}): void;
|
||||
declare function f40(x: number): void;
|
||||
declare function f41(x: number): void;
|
||||
declare function f42(x: number): void;
|
||||
@@ -0,0 +1,387 @@
|
||||
=== tests/cases/conformance/controlFlow/neverReturningFunctions1.ts ===
|
||||
function fail(message?: string): never {
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 0, 14))
|
||||
|
||||
throw new Error(message);
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 0, 14))
|
||||
}
|
||||
|
||||
function f01(x: string | undefined) {
|
||||
>f01 : Symbol(f01, Decl(neverReturningFunctions1.ts, 2, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 4, 13))
|
||||
|
||||
if (x === undefined) fail("undefined argument");
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 4, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x.length; // string
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 4, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
function f02(x: number): number {
|
||||
>f02 : Symbol(f02, Decl(neverReturningFunctions1.ts, 7, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13))
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13))
|
||||
|
||||
fail("negative number");
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13))
|
||||
}
|
||||
|
||||
function f03(x: string) {
|
||||
>f03 : Symbol(f03, Decl(neverReturningFunctions1.ts, 13, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 15, 13))
|
||||
|
||||
x; // string
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 15, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 15, 13))
|
||||
}
|
||||
|
||||
function f11(x: string | undefined, fail: (message?: string) => never) {
|
||||
>f11 : Symbol(f11, Decl(neverReturningFunctions1.ts, 19, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 21, 13))
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 21, 35))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 21, 43))
|
||||
|
||||
if (x === undefined) fail("undefined argument");
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 21, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 21, 35))
|
||||
|
||||
x.length; // string
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 21, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
function f12(x: number, fail: (message?: string) => never): number {
|
||||
>f12 : Symbol(f12, Decl(neverReturningFunctions1.ts, 24, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13))
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 26, 23))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 26, 31))
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13))
|
||||
|
||||
fail("negative number");
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 26, 23))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13))
|
||||
}
|
||||
|
||||
function f13(x: string, fail: (message?: string) => never) {
|
||||
>f13 : Symbol(f13, Decl(neverReturningFunctions1.ts, 30, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 32, 13))
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 32, 23))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 32, 31))
|
||||
|
||||
x; // string
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 32, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 32, 23))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 32, 13))
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1))
|
||||
|
||||
export declare function fail(message?: string): never;
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 39, 33))
|
||||
}
|
||||
|
||||
function f21(x: string | undefined) {
|
||||
>f21 : Symbol(f21, Decl(neverReturningFunctions1.ts, 40, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 42, 13))
|
||||
|
||||
if (x === undefined) Debug.fail("undefined argument");
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 42, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
>Debug.fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1))
|
||||
>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
|
||||
x.length; // string
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 42, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
function f22(x: number): number {
|
||||
>f22 : Symbol(f22, Decl(neverReturningFunctions1.ts, 45, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13))
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13))
|
||||
|
||||
Debug.fail("negative number");
|
||||
>Debug.fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1))
|
||||
>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13))
|
||||
}
|
||||
|
||||
function f23(x: string) {
|
||||
>f23 : Symbol(f23, Decl(neverReturningFunctions1.ts, 51, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 53, 13))
|
||||
|
||||
x; // string
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 53, 13))
|
||||
|
||||
Debug.fail();
|
||||
>Debug.fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1))
|
||||
>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 53, 13))
|
||||
}
|
||||
|
||||
function f24(x: string) {
|
||||
>f24 : Symbol(f24, Decl(neverReturningFunctions1.ts, 57, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 59, 13))
|
||||
|
||||
x; // string
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 59, 13))
|
||||
|
||||
((Debug).fail)();
|
||||
>(Debug).fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1))
|
||||
>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 59, 13))
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1))
|
||||
|
||||
fail(message?: string): never {
|
||||
>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 66, 9))
|
||||
|
||||
throw new Error(message);
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>message : Symbol(message, Decl(neverReturningFunctions1.ts, 66, 9))
|
||||
}
|
||||
f1(x: string | undefined) {
|
||||
>f1 : Symbol(Test.f1, Decl(neverReturningFunctions1.ts, 68, 5))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 69, 7))
|
||||
|
||||
if (x === undefined) this.fail("undefined argument");
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 69, 7))
|
||||
>undefined : Symbol(undefined)
|
||||
>this.fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
>this : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1))
|
||||
>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
|
||||
x.length; // string
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 69, 7))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
f2(x: number): number {
|
||||
>f2 : Symbol(Test.f2, Decl(neverReturningFunctions1.ts, 72, 5))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7))
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7))
|
||||
|
||||
this.fail("negative number");
|
||||
>this.fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
>this : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1))
|
||||
>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7))
|
||||
}
|
||||
f3(x: string) {
|
||||
>f3 : Symbol(Test.f3, Decl(neverReturningFunctions1.ts, 77, 5))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 78, 7))
|
||||
|
||||
x; // string
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 78, 7))
|
||||
|
||||
this.fail();
|
||||
>this.fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
>this : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1))
|
||||
>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 78, 7))
|
||||
}
|
||||
}
|
||||
|
||||
function f30(x: string | number | undefined) {
|
||||
>f30 : Symbol(f30, Decl(neverReturningFunctions1.ts, 83, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
|
||||
if (typeof x === "string") {
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
}
|
||||
else {
|
||||
x; // number | undefined
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
|
||||
if (x !== undefined) {
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
x; // number
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
}
|
||||
else {
|
||||
x; // undefined
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13))
|
||||
}
|
||||
|
||||
function f31(x: { a: string | number }) {
|
||||
>f31 : Symbol(f31, Decl(neverReturningFunctions1.ts, 105, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13))
|
||||
>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
|
||||
if (typeof x.a === "string") {
|
||||
>x.a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13))
|
||||
>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13))
|
||||
|
||||
x.a; // Unreachable
|
||||
>x.a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13))
|
||||
>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
}
|
||||
x; // { a: string | number }
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13))
|
||||
|
||||
x.a; // number
|
||||
>x.a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13))
|
||||
>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17))
|
||||
}
|
||||
|
||||
function f40(x: number) {
|
||||
>f40 : Symbol(f40, Decl(neverReturningFunctions1.ts, 115, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13))
|
||||
|
||||
try {
|
||||
x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13))
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13))
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13))
|
||||
}
|
||||
|
||||
function f41(x: number) {
|
||||
>f41 : Symbol(f41, Decl(neverReturningFunctions1.ts, 129, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13))
|
||||
|
||||
try {
|
||||
x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13))
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13))
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13))
|
||||
}
|
||||
|
||||
function f42(x: number) {
|
||||
>f42 : Symbol(f42, Decl(neverReturningFunctions1.ts, 141, 1))
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13))
|
||||
|
||||
try {
|
||||
x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13))
|
||||
|
||||
fail();
|
||||
>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0))
|
||||
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13))
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13))
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
=== tests/cases/conformance/controlFlow/neverReturningFunctions1.ts ===
|
||||
function fail(message?: string): never {
|
||||
>fail : (message?: string | undefined) => never
|
||||
>message : string | undefined
|
||||
|
||||
throw new Error(message);
|
||||
>new Error(message) : Error
|
||||
>Error : ErrorConstructor
|
||||
>message : string | undefined
|
||||
}
|
||||
|
||||
function f01(x: string | undefined) {
|
||||
>f01 : (x: string | undefined) => void
|
||||
>x : string | undefined
|
||||
|
||||
if (x === undefined) fail("undefined argument");
|
||||
>x === undefined : boolean
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
>fail("undefined argument") : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"undefined argument" : "undefined argument"
|
||||
|
||||
x.length; // string
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function f02(x: number): number {
|
||||
>f02 : (x: number) => number
|
||||
>x : number
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x >= 0 : boolean
|
||||
>x : number
|
||||
>0 : 0
|
||||
>x : number
|
||||
|
||||
fail("negative number");
|
||||
>fail("negative number") : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"negative number" : "negative number"
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
|
||||
function f03(x: string) {
|
||||
>f03 : (x: string) => void
|
||||
>x : string
|
||||
|
||||
x; // string
|
||||
>x : string
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string
|
||||
}
|
||||
|
||||
function f11(x: string | undefined, fail: (message?: string) => never) {
|
||||
>f11 : (x: string | undefined, fail: (message?: string | undefined) => never) => void
|
||||
>x : string | undefined
|
||||
>fail : (message?: string | undefined) => never
|
||||
>message : string | undefined
|
||||
|
||||
if (x === undefined) fail("undefined argument");
|
||||
>x === undefined : boolean
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
>fail("undefined argument") : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"undefined argument" : "undefined argument"
|
||||
|
||||
x.length; // string
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function f12(x: number, fail: (message?: string) => never): number {
|
||||
>f12 : (x: number, fail: (message?: string | undefined) => never) => number
|
||||
>x : number
|
||||
>fail : (message?: string | undefined) => never
|
||||
>message : string | undefined
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x >= 0 : boolean
|
||||
>x : number
|
||||
>0 : 0
|
||||
>x : number
|
||||
|
||||
fail("negative number");
|
||||
>fail("negative number") : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"negative number" : "negative number"
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
|
||||
function f13(x: string, fail: (message?: string) => never) {
|
||||
>f13 : (x: string, fail: (message?: string | undefined) => never) => void
|
||||
>x : string
|
||||
>fail : (message?: string | undefined) => never
|
||||
>message : string | undefined
|
||||
|
||||
x; // string
|
||||
>x : string
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
>Debug : typeof Debug
|
||||
|
||||
export declare function fail(message?: string): never;
|
||||
>fail : (message?: string | undefined) => never
|
||||
>message : string | undefined
|
||||
}
|
||||
|
||||
function f21(x: string | undefined) {
|
||||
>f21 : (x: string | undefined) => void
|
||||
>x : string | undefined
|
||||
|
||||
if (x === undefined) Debug.fail("undefined argument");
|
||||
>x === undefined : boolean
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
>Debug.fail("undefined argument") : never
|
||||
>Debug.fail : (message?: string | undefined) => never
|
||||
>Debug : typeof Debug
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"undefined argument" : "undefined argument"
|
||||
|
||||
x.length; // string
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
|
||||
function f22(x: number): number {
|
||||
>f22 : (x: number) => number
|
||||
>x : number
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x >= 0 : boolean
|
||||
>x : number
|
||||
>0 : 0
|
||||
>x : number
|
||||
|
||||
Debug.fail("negative number");
|
||||
>Debug.fail("negative number") : never
|
||||
>Debug.fail : (message?: string | undefined) => never
|
||||
>Debug : typeof Debug
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"negative number" : "negative number"
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
|
||||
function f23(x: string) {
|
||||
>f23 : (x: string) => void
|
||||
>x : string
|
||||
|
||||
x; // string
|
||||
>x : string
|
||||
|
||||
Debug.fail();
|
||||
>Debug.fail() : never
|
||||
>Debug.fail : (message?: string | undefined) => never
|
||||
>Debug : typeof Debug
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string
|
||||
}
|
||||
|
||||
function f24(x: string) {
|
||||
>f24 : (x: string) => void
|
||||
>x : string
|
||||
|
||||
x; // string
|
||||
>x : string
|
||||
|
||||
((Debug).fail)();
|
||||
>((Debug).fail)() : never
|
||||
>((Debug).fail) : (message?: string | undefined) => never
|
||||
>(Debug).fail : (message?: string | undefined) => never
|
||||
>(Debug) : typeof Debug
|
||||
>Debug : typeof Debug
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
fail(message?: string): never {
|
||||
>fail : (message?: string | undefined) => never
|
||||
>message : string | undefined
|
||||
|
||||
throw new Error(message);
|
||||
>new Error(message) : Error
|
||||
>Error : ErrorConstructor
|
||||
>message : string | undefined
|
||||
}
|
||||
f1(x: string | undefined) {
|
||||
>f1 : (x: string | undefined) => void
|
||||
>x : string | undefined
|
||||
|
||||
if (x === undefined) this.fail("undefined argument");
|
||||
>x === undefined : boolean
|
||||
>x : string | undefined
|
||||
>undefined : undefined
|
||||
>this.fail("undefined argument") : never
|
||||
>this.fail : (message?: string | undefined) => never
|
||||
>this : this
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"undefined argument" : "undefined argument"
|
||||
|
||||
x.length; // string
|
||||
>x.length : number
|
||||
>x : string
|
||||
>length : number
|
||||
}
|
||||
f2(x: number): number {
|
||||
>f2 : (x: number) => number
|
||||
>x : number
|
||||
|
||||
if (x >= 0) return x;
|
||||
>x >= 0 : boolean
|
||||
>x : number
|
||||
>0 : 0
|
||||
>x : number
|
||||
|
||||
this.fail("negative number");
|
||||
>this.fail("negative number") : never
|
||||
>this.fail : (message?: string | undefined) => never
|
||||
>this : this
|
||||
>fail : (message?: string | undefined) => never
|
||||
>"negative number" : "negative number"
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
f3(x: string) {
|
||||
>f3 : (x: string) => void
|
||||
>x : string
|
||||
|
||||
x; // string
|
||||
>x : string
|
||||
|
||||
this.fail();
|
||||
>this.fail() : never
|
||||
>this.fail : (message?: string | undefined) => never
|
||||
>this : this
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string
|
||||
}
|
||||
}
|
||||
|
||||
function f30(x: string | number | undefined) {
|
||||
>f30 : (x: string | number | undefined) => void
|
||||
>x : string | number | undefined
|
||||
|
||||
if (typeof x === "string") {
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : string | number | undefined
|
||||
>"string" : "string"
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string | number | undefined
|
||||
}
|
||||
else {
|
||||
x; // number | undefined
|
||||
>x : number | undefined
|
||||
|
||||
if (x !== undefined) {
|
||||
>x !== undefined : boolean
|
||||
>x : number | undefined
|
||||
>undefined : undefined
|
||||
|
||||
x; // number
|
||||
>x : number
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string | number | undefined
|
||||
}
|
||||
else {
|
||||
x; // undefined
|
||||
>x : undefined
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : string | number | undefined
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : string | number | undefined
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : string | number | undefined
|
||||
}
|
||||
|
||||
function f31(x: { a: string | number }) {
|
||||
>f31 : (x: { a: string | number; }) => void
|
||||
>x : { a: string | number; }
|
||||
>a : string | number
|
||||
|
||||
if (typeof x.a === "string") {
|
||||
>typeof x.a === "string" : boolean
|
||||
>typeof x.a : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x.a : string | number
|
||||
>x : { a: string | number; }
|
||||
>a : string | number
|
||||
>"string" : "string"
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : { a: string | number; }
|
||||
|
||||
x.a; // Unreachable
|
||||
>x.a : string | number
|
||||
>x : { a: string | number; }
|
||||
>a : string | number
|
||||
}
|
||||
x; // { a: string | number }
|
||||
>x : { a: string | number; }
|
||||
|
||||
x.a; // number
|
||||
>x.a : number
|
||||
>x : { a: string | number; }
|
||||
>a : number
|
||||
}
|
||||
|
||||
function f40(x: number) {
|
||||
>f40 : (x: number) => void
|
||||
>x : number
|
||||
|
||||
try {
|
||||
x;
|
||||
>x : number
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
>x : number
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
|
||||
function f41(x: number) {
|
||||
>f41 : (x: number) => void
|
||||
>x : number
|
||||
|
||||
try {
|
||||
x;
|
||||
>x : number
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
>x : number
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
|
||||
function f42(x: number) {
|
||||
>f42 : (x: number) => void
|
||||
>x : number
|
||||
|
||||
try {
|
||||
x;
|
||||
>x : number
|
||||
|
||||
fail();
|
||||
>fail() : never
|
||||
>fail : (message?: string | undefined) => never
|
||||
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
>x : number
|
||||
}
|
||||
x; // Unreachable
|
||||
>x : number
|
||||
}
|
||||
|
||||
@@ -40,3 +40,17 @@ function foo5(bar: "a" | "b"): number {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function foo6(bar: "a", a: boolean, b: boolean): number {
|
||||
if (a) {
|
||||
switch (bar) {
|
||||
case "a": return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (b) {
|
||||
case true: return -1;
|
||||
case false: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
declare function isString(value: unknown): value is string;
|
||||
declare function isArrayOfStrings(value: unknown): value is string[];
|
||||
|
||||
const assert: (value: unknown) => asserts value = value => {}
|
||||
|
||||
declare function assertIsString(value: unknown): asserts value is string;
|
||||
declare function assertIsArrayOfStrings(value: unknown): asserts value is string[];
|
||||
declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
|
||||
function f01(x: unknown) {
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x instanceof Error);
|
||||
x.message;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof x === "boolean" || typeof x === "number");
|
||||
x.toLocaleString;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(isArrayOfStrings(x));
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsArrayOfStrings(x);
|
||||
x[0].length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x === undefined || typeof x === "string");
|
||||
x; // string | undefined
|
||||
assertDefined(x);
|
||||
x; // string
|
||||
}
|
||||
}
|
||||
|
||||
function f02(x: string | undefined) {
|
||||
if (!!true) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
|
||||
function f03(x: string | undefined, assert: (value: unknown) => asserts value) {
|
||||
assert(x);
|
||||
x.length;
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
export declare function assert(value: unknown, message?: string): asserts value;
|
||||
export declare function assertDefined<T>(value: T): asserts value is NonNullable<T>;
|
||||
}
|
||||
|
||||
function f10(x: string | undefined) {
|
||||
if (!!true) {
|
||||
Debug.assert(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assert(x !== undefined);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
Debug.assertDefined(x);
|
||||
x.length;
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
assert(value: unknown): asserts value {
|
||||
if (value) return;
|
||||
throw new Error();
|
||||
}
|
||||
isTest2(): this is Test2 {
|
||||
return this instanceof Test2;
|
||||
}
|
||||
assertIsTest2(): asserts this is Test2 {
|
||||
if (this instanceof Test2) return;
|
||||
throw new Error();
|
||||
}
|
||||
assertThis(): asserts this {
|
||||
if (!this) return;
|
||||
throw new Error();
|
||||
}
|
||||
bar() {
|
||||
this.assertThis();
|
||||
this;
|
||||
}
|
||||
foo(x: unknown) {
|
||||
this.assert(typeof x === "string");
|
||||
x.length;
|
||||
if (this.isTest2()) {
|
||||
this.z;
|
||||
}
|
||||
this.assertIsTest2();
|
||||
this.z;
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 extends Test {
|
||||
z = 0;
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
|
||||
declare class Wat {
|
||||
get p1(): this is string;
|
||||
set p1(x: this is string);
|
||||
get p2(): asserts this is string;
|
||||
set p2(x: asserts this is string);
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
// @strict: true
|
||||
// @allowUnreachableCode: false
|
||||
// @declaration: true
|
||||
|
||||
function f1(x: 1 | 2): string {
|
||||
if (!!true) {
|
||||
switch (x) {
|
||||
case 1: return 'a';
|
||||
case 2: return 'b';
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
|
||||
function f2(x: 1 | 2) {
|
||||
let z: number;
|
||||
switch (x) {
|
||||
case 1: z = 10; break;
|
||||
case 2: z = 20; break;
|
||||
}
|
||||
z; // Definitely assigned
|
||||
}
|
||||
|
||||
function f3(x: 1 | 2) {
|
||||
switch (x) {
|
||||
case 1: return 10;
|
||||
case 2: return 20;
|
||||
// Default considered reachable to allow defensive coding
|
||||
default: throw new Error("Bad input");
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #11572
|
||||
|
||||
enum E { A, B }
|
||||
|
||||
function f(e: E): number {
|
||||
switch (e) {
|
||||
case E.A: return 0
|
||||
case E.B: return 1
|
||||
}
|
||||
}
|
||||
|
||||
function g(e: E): number {
|
||||
if (!true)
|
||||
return -1
|
||||
else
|
||||
switch (e) {
|
||||
case E.A: return 0
|
||||
case E.B: return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #12668
|
||||
|
||||
interface Square { kind: "square"; size: number; }
|
||||
|
||||
interface Rectangle { kind: "rectangle"; width: number; height: number; }
|
||||
|
||||
interface Circle { kind: "circle"; radius: number; }
|
||||
|
||||
interface Triangle { kind: "triangle"; side: number; }
|
||||
|
||||
type Shape = Square | Rectangle | Circle | Triangle;
|
||||
|
||||
function area(s: Shape): number {
|
||||
let area;
|
||||
switch (s.kind) {
|
||||
case "square": area = s.size * s.size; break;
|
||||
case "rectangle": area = s.width * s.height; break;
|
||||
case "circle": area = Math.PI * s.radius * s.radius; break;
|
||||
case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
function areaWrapped(s: Shape): number {
|
||||
let area;
|
||||
area = (() => {
|
||||
switch (s.kind) {
|
||||
case "square": return s.size * s.size;
|
||||
case "rectangle": return s.width * s.height;
|
||||
case "circle": return Math.PI * s.radius * s.radius;
|
||||
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
|
||||
}
|
||||
})();
|
||||
return area;
|
||||
}
|
||||
|
||||
// Repro from #13241
|
||||
|
||||
enum MyEnum {
|
||||
A,
|
||||
B
|
||||
}
|
||||
|
||||
function thisGivesError(e: MyEnum): string {
|
||||
let s: string;
|
||||
switch (e) {
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function good1(e: MyEnum): string {
|
||||
let s: string;
|
||||
switch (e) {
|
||||
case MyEnum.A: s = "it was A"; break;
|
||||
case MyEnum.B: s = "it was B"; break;
|
||||
default: s = "it was something else"; break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function good2(e: MyEnum): string {
|
||||
switch (e) {
|
||||
case MyEnum.A: return "it was A";
|
||||
case MyEnum.B: return "it was B";
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #18362
|
||||
|
||||
enum Level {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
const doSomethingWithLevel = (level: Level) => {
|
||||
let next: Level;
|
||||
switch (level) {
|
||||
case Level.One:
|
||||
next = Level.Two;
|
||||
break;
|
||||
case Level.Two:
|
||||
next = Level.One;
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
};
|
||||
|
||||
// Repro from #20409
|
||||
|
||||
interface Square2 {
|
||||
kind: "square";
|
||||
size: number;
|
||||
}
|
||||
|
||||
interface Circle2 {
|
||||
kind: "circle";
|
||||
radius: number;
|
||||
}
|
||||
|
||||
type Shape2 = Square2 | Circle2;
|
||||
|
||||
function withDefault(s1: Shape2, s2: Shape2): string {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
default:
|
||||
return "never";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function withoutDefault(s1: Shape2, s2: Shape2): string {
|
||||
switch (s1.kind) {
|
||||
case "square":
|
||||
return "1";
|
||||
case "circle":
|
||||
switch (s2.kind) {
|
||||
case "square":
|
||||
return "2";
|
||||
case "circle":
|
||||
return "3";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #20823
|
||||
|
||||
function test4(value: 1 | 2) {
|
||||
let x: string;
|
||||
switch (value) {
|
||||
case 1: x = "one"; break;
|
||||
case 2: x = "two"; break;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
// @strict: true
|
||||
// @allowUnreachableCode: false
|
||||
// @declaration: true
|
||||
|
||||
function fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
function f01(x: string | undefined) {
|
||||
if (x === undefined) fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f02(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f03(x: string) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f11(x: string | undefined, fail: (message?: string) => never) {
|
||||
if (x === undefined) fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f12(x: number, fail: (message?: string) => never): number {
|
||||
if (x >= 0) return x;
|
||||
fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f13(x: string, fail: (message?: string) => never) {
|
||||
x; // string
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
namespace Debug {
|
||||
export declare function fail(message?: string): never;
|
||||
}
|
||||
|
||||
function f21(x: string | undefined) {
|
||||
if (x === undefined) Debug.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
|
||||
function f22(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
Debug.fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f23(x: string) {
|
||||
x; // string
|
||||
Debug.fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f24(x: string) {
|
||||
x; // string
|
||||
((Debug).fail)();
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
class Test {
|
||||
fail(message?: string): never {
|
||||
throw new Error(message);
|
||||
}
|
||||
f1(x: string | undefined) {
|
||||
if (x === undefined) this.fail("undefined argument");
|
||||
x.length; // string
|
||||
}
|
||||
f2(x: number): number {
|
||||
if (x >= 0) return x;
|
||||
this.fail("negative number");
|
||||
x; // Unreachable
|
||||
}
|
||||
f3(x: string) {
|
||||
x; // string
|
||||
this.fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
}
|
||||
|
||||
function f30(x: string | number | undefined) {
|
||||
if (typeof x === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
x; // number | undefined
|
||||
if (x !== undefined) {
|
||||
x; // number
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
else {
|
||||
x; // undefined
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f31(x: { a: string | number }) {
|
||||
if (typeof x.a === "string") {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
x.a; // Unreachable
|
||||
}
|
||||
x; // { a: string | number }
|
||||
x.a; // number
|
||||
}
|
||||
|
||||
function f40(x: number) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f41(x: number) {
|
||||
try {
|
||||
x;
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
|
||||
function f42(x: number) {
|
||||
try {
|
||||
x;
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
finally {
|
||||
x;
|
||||
}
|
||||
x; // Unreachable
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @allowUnreachableCode: false
|
||||
// @filename: assertionsAndNonReturningFunctions.js
|
||||
|
||||
/** @typedef {(check: boolean) => asserts check} AssertFunc */
|
||||
|
||||
/** @type {AssertFunc} */
|
||||
const assert = check => {
|
||||
if (!check) throw new Error();
|
||||
}
|
||||
|
||||
/** @type {(x: unknown) => asserts x is string } */
|
||||
function assertIsString(x) {
|
||||
if (!(typeof x === "string")) throw new Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} check
|
||||
* @returns {asserts check}
|
||||
*/
|
||||
function assert2(check) {
|
||||
if (!check) throw new Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {never}
|
||||
*/
|
||||
function fail() {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} x
|
||||
*/
|
||||
function f1(x) {
|
||||
if (!!true) {
|
||||
assert(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assert2(typeof x === "string");
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
assertIsString(x);
|
||||
x.length;
|
||||
}
|
||||
if (!!true) {
|
||||
fail();
|
||||
x; // Unreachable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} b
|
||||
*/
|
||||
function f2(b) {
|
||||
switch (b) {
|
||||
case true: return 1;
|
||||
case false: return 0;
|
||||
}
|
||||
b; // Unreachable
|
||||
}
|
||||
Reference in New Issue
Block a user