From b1a8a5fe664fbe96a0c0bbad3c4003aa13958407 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Sun, 7 Jun 2015 18:31:53 +0800 Subject: [PATCH] Addresses CR feedback --- src/compiler/checker.ts | 41 ++++++++--- .../diagnosticInformationMap.generated.ts | 5 +- src/compiler/diagnosticMessages.json | 8 ++- .../baselines/reference/typeGuardFunction.js | 5 ++ .../reference/typeGuardFunction.symbols | 66 +++++++++-------- .../reference/typeGuardFunction.types | 11 +++ .../typeGuardFunctionErrors.errors.txt | 71 ++++++++++++------- .../reference/typeGuardFunctionErrors.js | 33 +++++++-- .../typeGuards/typeGuardFunction.ts | 5 ++ .../typeGuards/typeGuardFunctionErrors.ts | 22 ++++-- 10 files changed, 192 insertions(+), 75 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c7ccb98f8f2..720a2352b4f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8601,15 +8601,16 @@ module ts { } } - function isInATypePredicateCompatiblePosition(node: Node): boolean { + function isInLegalTypePredicatePosition(node: Node): boolean { switch (node.parent.kind) { case SyntaxKind.ArrowFunction: + case SyntaxKind.CallSignature: case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.FunctionType: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: - return true; + return node === (node.parent).type; } return false; } @@ -8634,11 +8635,11 @@ module ts { if (node.type.kind === SyntaxKind.TypePredicate) { let typePredicate = getSignatureFromDeclaration(node).typePredicate; let typePredicateNode = node.type; - if (isInATypePredicateCompatiblePosition(typePredicateNode)) { + if (isInLegalTypePredicatePosition(typePredicateNode)) { if (typePredicate.parameterIndex >= 0) { if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) { error(typePredicateNode.parameterName, - Diagnostics.Type_predicate_cannot_reference_a_spread_parameter); + Diagnostics.Type_predicate_cannot_reference_a_rest_parameter); } else { checkTypeAssignableTo(typePredicate.type, @@ -8647,14 +8648,34 @@ module ts { } } else if (typePredicateNode.parameterName) { - error(typePredicateNode.parameterName, - Diagnostics.Cannot_find_parameter_0, - typePredicate.parameterName); + let hasReportedError = false; + outer: for (let param of node.parameters) { + if (param.name.kind === SyntaxKind.ObjectBindingPattern || + param.name.kind === SyntaxKind.ArrayBindingPattern) { + + for (let element of (param.name).elements) { + if (element.name.kind === SyntaxKind.Identifier && + (element.name).text === typePredicateNode.parameterName.text) { + + error(typePredicateNode.parameterName, + Diagnostics.Type_predicate_cannot_reference_element_0_in_a_binding_pattern, + typePredicate.parameterName); + hasReportedError = true; + break outer; + } + } + } + } + if (!hasReportedError) { + error(typePredicateNode.parameterName, + Diagnostics.Cannot_find_parameter_0, + typePredicate.parameterName); + } } } else { error(typePredicateNode, - Diagnostics.Type_predicates_are_only_allowed_in_return_type_position_for_arrow_functions_function_expressions_function_declarations_function_types_and_method_declarations); + Diagnostics.Type_predicates_are_only_allowed_in_return_type_position_for_functions_and_methods); } } else { @@ -11295,8 +11316,8 @@ module ts { } function checkTypePredicate(node: TypePredicateNode) { - if(!isInATypePredicateCompatiblePosition(node)) { - error(node, Diagnostics.Type_predicates_are_only_allowed_in_return_type_position_for_arrow_functions_function_expressions_function_declarations_function_types_and_method_declarations); + if(!isInLegalTypePredicatePosition(node)) { + error(node, Diagnostics.Type_predicates_are_only_allowed_in_return_type_position_for_functions_and_methods); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 25d3730cc07..96480f17ac3 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -183,8 +183,9 @@ module ts { Cannot_find_parameter_0: { code: 1225, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." }, Type_predicate_0_is_not_assignable_to_1: { code: 1226, category: DiagnosticCategory.Error, key: "Type predicate '{0}' is not assignable to '{1}'." }, Parameter_0_is_not_in_the_same_position_as_parameter_1: { code: 1227, category: DiagnosticCategory.Error, key: "Parameter '{0}' is not in the same position as parameter '{1}'." }, - Type_predicates_are_only_allowed_in_return_type_position_for_arrow_functions_function_expressions_function_declarations_function_types_and_method_declarations: { code: 1228, category: DiagnosticCategory.Error, key: "Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations." }, - Type_predicate_cannot_reference_a_spread_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "Type predicate cannot reference a spread parameter." }, + Type_predicates_are_only_allowed_in_return_type_position_for_functions_and_methods: { code: 1228, category: DiagnosticCategory.Error, key: "Type predicates are only allowed in return type position for functions and methods." }, + Type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "Type predicate cannot reference a rest parameter." }, + Type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: DiagnosticCategory.Error, key: "Type predicate cannot reference element '{0}' in a binding pattern." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4008a6af1b1..64b9c93fd60 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -719,14 +719,18 @@ "category": "Error", "code": 1227 }, - "Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations.": { + "Type predicates are only allowed in return type position for functions and methods.": { "category": "Error", "code": 1228 }, - "Type predicate cannot reference a spread parameter.": { + "Type predicate cannot reference a rest parameter.": { "category": "Error", "code": 1229 }, + "Type predicate cannot reference element '{0}' in a binding pattern.": { + "category": "Error", + "code": 1230 + }, "Duplicate identifier '{0}'.": { diff --git a/tests/baselines/reference/typeGuardFunction.js b/tests/baselines/reference/typeGuardFunction.js index 5c256160bba..f6b752c8c04 100644 --- a/tests/baselines/reference/typeGuardFunction.js +++ b/tests/baselines/reference/typeGuardFunction.js @@ -38,6 +38,11 @@ if(isA(union)) { union.propA; } +// Call signature +interface I1 { + (p1: A): p1 is C; +} + // The parameter index and argument index for the type guard target is matching. // The type predicate type is assignable to the parameter type. declare function isC_multipleParams(p1, p2): p1 is C; diff --git a/tests/baselines/reference/typeGuardFunction.symbols b/tests/baselines/reference/typeGuardFunction.symbols index 5b5fe1ec855..c315e721085 100644 --- a/tests/baselines/reference/typeGuardFunction.symbols +++ b/tests/baselines/reference/typeGuardFunction.symbols @@ -91,16 +91,26 @@ if(isA(union)) { >propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9)) } +// Call signature +interface I1 { +>I1 : Symbol(I1, Decl(typeGuardFunction.ts, 37, 1)) + + (p1: A): p1 is C; +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 41, 5)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +} + // The parameter index and argument index for the type guard target is matching. // The type predicate type is assignable to the parameter type. declare function isC_multipleParams(p1, p2): p1 is C; ->isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 37, 1)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 41, 36)) ->p2 : Symbol(p2, Decl(typeGuardFunction.ts, 41, 39)) +>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 42, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 46, 36)) +>p2 : Symbol(p2, Decl(typeGuardFunction.ts, 46, 39)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) if (isC_multipleParams(a, 0)) { ->isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 37, 1)) +>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 42, 1)) >a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) a.propC; @@ -111,20 +121,20 @@ if (isC_multipleParams(a, 0)) { // Methods var obj: { ->obj : Symbol(obj, Decl(typeGuardFunction.ts, 47, 3)) +>obj : Symbol(obj, Decl(typeGuardFunction.ts, 52, 3)) func1(p1: A): p1 is C; ->func1 : Symbol(func1, Decl(typeGuardFunction.ts, 47, 10)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 48, 10)) +>func1 : Symbol(func1, Decl(typeGuardFunction.ts, 52, 10)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 53, 10)) >A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) } class D { ->D : Symbol(D, Decl(typeGuardFunction.ts, 49, 1)) +>D : Symbol(D, Decl(typeGuardFunction.ts, 54, 1)) method1(p1: A): p1 is C { ->method1 : Symbol(method1, Decl(typeGuardFunction.ts, 50, 9)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 51, 12)) +>method1 : Symbol(method1, Decl(typeGuardFunction.ts, 55, 9)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 56, 12)) >A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) @@ -134,23 +144,23 @@ class D { // Arrow function let f1 = (p1: A): p1 is C => false; ->f1 : Symbol(f1, Decl(typeGuardFunction.ts, 57, 3)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 57, 10)) +>f1 : Symbol(f1, Decl(typeGuardFunction.ts, 62, 3)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 62, 10)) >A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) // Function type declare function f2(p1: (p1: A) => p1 is C); ->f2 : Symbol(f2, Decl(typeGuardFunction.ts, 57, 35)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 60, 20)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 60, 25)) +>f2 : Symbol(f2, Decl(typeGuardFunction.ts, 62, 35)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 65, 20)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 65, 25)) >A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) // Function expressions f2(function(p1: A): p1 is C { ->f2 : Symbol(f2, Decl(typeGuardFunction.ts, 57, 35)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 63, 12)) +>f2 : Symbol(f2, Decl(typeGuardFunction.ts, 62, 35)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 68, 12)) >A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) @@ -159,35 +169,35 @@ f2(function(p1: A): p1 is C { // Evaluations are asssignable to boolean. declare function acceptingBoolean(a: boolean); ->acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 65, 3)) ->a : Symbol(a, Decl(typeGuardFunction.ts, 68, 34)) +>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 70, 3)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 73, 34)) acceptingBoolean(isA(a)); ->acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 65, 3)) +>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 70, 3)) >isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) >a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) // Type predicates with different parameter name. declare function acceptingTypeGuardFunction(p1: (item) => item is A); ->acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 69, 25)) ->p1 : Symbol(p1, Decl(typeGuardFunction.ts, 72, 44)) ->item : Symbol(item, Decl(typeGuardFunction.ts, 72, 49)) +>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 74, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 77, 44)) +>item : Symbol(item, Decl(typeGuardFunction.ts, 77, 49)) >A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) acceptingTypeGuardFunction(isA); ->acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 69, 25)) +>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 74, 25)) >isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) // Binary expressions let union2: C | B; ->union2 : Symbol(union2, Decl(typeGuardFunction.ts, 76, 3)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3)) >C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) >B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) let union3: boolean | B = isA(union2) || union2; ->union3 : Symbol(union3, Decl(typeGuardFunction.ts, 77, 3)) +>union3 : Symbol(union3, Decl(typeGuardFunction.ts, 82, 3)) >B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) >isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) ->union2 : Symbol(union2, Decl(typeGuardFunction.ts, 76, 3)) ->union2 : Symbol(union2, Decl(typeGuardFunction.ts, 76, 3)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3)) diff --git a/tests/baselines/reference/typeGuardFunction.types b/tests/baselines/reference/typeGuardFunction.types index 06e9be615e2..cf673f965f9 100644 --- a/tests/baselines/reference/typeGuardFunction.types +++ b/tests/baselines/reference/typeGuardFunction.types @@ -97,6 +97,17 @@ if(isA(union)) { >propA : number } +// Call signature +interface I1 { +>I1 : I1 + + (p1: A): p1 is C; +>p1 : A +>A : A +>p1 : any +>C : C +} + // The parameter index and argument index for the type guard target is matching. // The type predicate type is assignable to the parameter type. declare function isC_multipleParams(p1, p2): p1 is C; diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index bcef83601aa..337dcd317c9 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -20,19 +20,22 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(81,1): Type predicate 'p2 is A' is not assignable to 'p1 is A'. Parameter 'p2' is not in the same position as parameter 'p1'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(87,1): error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,56): error TS1225: Cannot find parameter 'p1'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,9): error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,16): error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,20): error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(103,25): error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(104,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(106,20): error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(109,20): error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(110,16): error TS2408: Setters cannot return a value. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(115,20): error TS1229: Type predicate cannot reference a spread parameter. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,9): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(93,16): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(94,20): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(100,25): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(101,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(103,20): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(106,20): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(107,16): error TS2408: Setters cannot return a value. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(112,18): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(116,22): error TS1228: Type predicates are only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,20): error TS1229: Type predicate cannot reference a rest parameter. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(125,34): error TS1230: Type predicate cannot reference element 'p1' in a binding pattern. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(129,34): error TS1230: Type predicate cannot reference element 'p1' in a binding pattern. -==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (26 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (29 errors) ==== class A { propA: number; @@ -161,21 +164,16 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(115,20 return true; }; - // Type guard paramater referring to a binding pattern - declare function destructureParameter({ p1, p2, p3 }): p1 is A; - ~~ -!!! error TS1225: Cannot find parameter 'p1'. - // Type predicates in non-return type positions var b1: b is A; ~~~~~~ -!!! error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. function b2(a: b is A) {}; ~~~~~~ -!!! error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. function b3(): A | b is A { ~~~~~~ -!!! error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. return true; }; @@ -183,28 +181,53 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(115,20 class D { constructor(p1: A): p1 is C { ~~~~~~~ -!!! error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. return true; ~~~~ !!! error TS2409: Return type of constructor signature must be assignable to the instance type of the class } get m1(p1: A): p1 is C { ~~~~~~~ -!!! error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. return true; } set m2(p1: A): p1 is C { ~~~~~~~ -!!! error TS1228: Type predicates are only allowed in return type position for arrow functions, function expressions, function declarations, function types and method declarations. +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. return true; ~~~~ !!! error TS2408: Setters cannot return a value. } } - // Reference to spread parameter + interface I1 { + new (p1: A): p1 is C; + ~~~~~~~ +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. + } + + interface I2 { + [index: number]: p1 is C; + ~~~~~~~ +!!! error TS1228: Type predicates are only allowed in return type position for functions and methods. + } + + // Reference to rest parameter function b4(...a): a is A { ~ -!!! error TS1229: Type predicate cannot reference a spread parameter. +!!! error TS1229: Type predicate cannot reference a rest parameter. + return true; + } + + // Reference to binding pattern + function b5({a, b, p1}, p2, p3): p1 is A { + ~~ +!!! error TS1230: Type predicate cannot reference element 'p1' in a binding pattern. + return true; + } + + function b6([a, b, p1], p2, p3): p1 is A { + ~~ +!!! error TS1230: Type predicate cannot reference element 'p1' in a binding pattern. return true; } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardFunctionErrors.js b/tests/baselines/reference/typeGuardFunctionErrors.js index 2d3ccc561ed..354aae2f2a1 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.js +++ b/tests/baselines/reference/typeGuardFunctionErrors.js @@ -89,9 +89,6 @@ assign3 = function(p1, p2, p3): p1 is A { return true; }; -// Type guard paramater referring to a binding pattern -declare function destructureParameter({ p1, p2, p3 }): p1 is A; - // Type predicates in non-return type positions var b1: b is A; function b2(a: b is A) {}; @@ -112,9 +109,26 @@ class D { } } -// Reference to spread parameter +interface I1 { + new (p1: A): p1 is C; +} + +interface I2 { + [index: number]: p1 is C; +} + +// Reference to rest parameter function b4(...a): a is A { return true; +} + +// Reference to binding pattern +function b5({a, b, p1}, p2, p3): p1 is A { + return true; +} + +function b6([a, b, p1], p2, p3): p1 is A { + return true; } //// [typeGuardFunctionErrors.js] @@ -222,7 +236,7 @@ var D = (function () { }); return D; })(); -// Reference to spread parameter +// Reference to rest parameter function b4() { var a = []; for (var _i = 0; _i < arguments.length; _i++) { @@ -230,3 +244,12 @@ function b4() { } return true; } +// Reference to binding pattern +function b5(_a, p2, p3) { + var a = _a.a, b = _a.b, p1 = _a.p1; + return true; +} +function b6(_a, p2, p3) { + var a = _a[0], b = _a[1], p1 = _a[2]; + return true; +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts index 316a1483380..57d56ccc3b6 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts @@ -37,6 +37,11 @@ if(isA(union)) { union.propA; } +// Call signature +interface I1 { + (p1: A): p1 is C; +} + // The parameter index and argument index for the type guard target is matching. // The type predicate type is assignable to the parameter type. declare function isC_multipleParams(p1, p2): p1 is C; diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts index df1d0b974c4..e7012a172b0 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts @@ -88,9 +88,6 @@ assign3 = function(p1, p2, p3): p1 is A { return true; }; -// Type guard paramater referring to a binding pattern -declare function destructureParameter({ p1, p2, p3 }): p1 is A; - // Type predicates in non-return type positions var b1: b is A; function b2(a: b is A) {}; @@ -111,7 +108,24 @@ class D { } } -// Reference to spread parameter +interface I1 { + new (p1: A): p1 is C; +} + +interface I2 { + [index: number]: p1 is C; +} + +// Reference to rest parameter function b4(...a): a is A { return true; +} + +// Reference to binding pattern +function b5({a, b, p1}, p2, p3): p1 is A { + return true; +} + +function b6([a, b, p1], p2, p3): p1 is A { + return true; } \ No newline at end of file