@@ -10963,6 +10963,87 @@ namespace ts {
10963
10963
return -1;
10964
10964
}
10965
10965
10966
+ function checkTypePredicate(node: TypePredicateNode) {
10967
+ const parent = getTypePredicateParent(node);
10968
+ if (!parent) {
10969
+ error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
10970
+ return;
10971
+ }
10972
+
10973
+ const typePredicate = getSignatureFromDeclaration(parent).typePredicate;
10974
+ if (typePredicate.parameterIndex >= 0) {
10975
+ if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) {
10976
+ error(node.parameterName,
10977
+ Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
10978
+ }
10979
+ else {
10980
+ checkTypeAssignableTo(typePredicate.type,
10981
+ getTypeOfNode(parent.parameters[typePredicate.parameterIndex]),
10982
+ node.type);
10983
+ }
10984
+ }
10985 + else if (node.parameterName) {
10986
+ let hasReportedError = false;
10987
+ for (var param of parent.parameters) {
10988
+ if (hasReportedError) {
10989
+ break;
10990
+ }
10991
+ if (param.name.kind === SyntaxKind.ObjectBindingPattern ||
10992
+ param.name.kind === SyntaxKind.ArrayBindingPattern) {
10993
+
10994
+ (function checkBindingPattern(pattern: BindingPattern) {
10995
+ for (const element of pattern.elements) {
10996
+ if (element.name.kind === SyntaxKind.Identifier &&
10997
+ (<Identifier>element.name).text === typePredicate.parameterName) {
10998
+
10999
+ error(node.parameterName,
11000
+ Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
11001
+ typePredicate.parameterName);
11002
+ hasReportedError = true;
11003
+ break;
11004
+ }
11005
+ else if (element.name.kind === SyntaxKind.ArrayBindingPattern ||
11006
+ element.name.kind === SyntaxKind.ObjectBindingPattern) {
11007
+
11008
+ checkBindingPattern(<BindingPattern>element.name);
11009
+ }
11010
+ }
11011
+ })(<BindingPattern>param.name);
11012
+ }
11013
+ }
11014
+ if (!hasReportedError) {
11015
+ error(node.parameterName,
11016
+ Diagnostics.Cannot_find_parameter_0,
11017
+ typePredicate.parameterName);
11018
+ }
11019
+ }
11020
+
11021
+ if (node.type && node.type.kind === SyntaxKind.UnionType) {
11022
+ for (const type of (<UnionTypeNode>node.type).types) {
11023
+ if (type.kind === SyntaxKind.TypePredicate) {
11024
+ checkTypePredicate(<TypePredicateNode>type);
11025
+ }
11026
+ }
11027
+ }
11028
+ }
11029
+
11030
+ function getTypePredicateParent(node: Node): SignatureDeclaration {
11031
+ switch (node.parent.kind) {
11032
+ case SyntaxKind.ArrowFunction:
11033
+ case SyntaxKind.CallSignature:
11034
+ case SyntaxKind.FunctionDeclaration:
11035
+ case SyntaxKind.FunctionExpression:
11036
+ case SyntaxKind.FunctionType:
11037
+ case SyntaxKind.MethodDeclaration:
11038
+ case SyntaxKind.MethodSignature:
11039
+ const parent = <SignatureDeclaration>node.parent;
11040
+ if(node === parent.type) {
11041
+ return parent;
11042
+ }
11043
+ }
11044
+ return undefined;
11045
+ }
11046
+
10966
11047
function isInLegalTypePredicatePosition(node: Node): boolean {
10967
11048
switch (node.parent.kind) {
10968
11049
case SyntaxKind.ArrowFunction:
@@ -10993,66 +11074,9 @@ namespace ts {
10993
11074
10994
11075
forEach(node.parameters, checkParameter);
10995
11076
10996
- if (node.type) {
10997
- if (node.type.kind === SyntaxKind.TypePredicate) {
10998
- const typePredicate = getSignatureFromDeclaration(node).typePredicate;
10999
- const typePredicateNode = <TypePredicateNode>node.type;
11000
- if (isInLegalTypePredicatePosition(typePredicateNode)) {
11001
- if (typePredicate.parameterIndex >= 0) {
11002
- if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) {
11003
- error(typePredicateNode.parameterName,
11004
- Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
11005
- }
11006
- else {
11007
- checkTypeAssignableTo(typePredicate.type,
11008
- getTypeOfNode(node.parameters[typePredicate.parameterIndex]),
11009
- typePredicateNode.type);
11010
- }
11011
- }
11012
- else if (typePredicateNode.parameterName) {
11013
- let hasReportedError = false;
11014
- for (var param of node.parameters) {
11015
- if (hasReportedError) {
11016
- break;
11017
- }
11018
- if (param.name.kind === SyntaxKind.ObjectBindingPattern ||
11019
- param.name.kind === SyntaxKind.ArrayBindingPattern) {
11020
-
11021
- (function checkBindingPattern(pattern: BindingPattern) {
11022
- for (const element of pattern.elements) {
11023
- if (element.name.kind === SyntaxKind.Identifier &&
11024
- (<Identifier>element.name).text === typePredicate.parameterName) {
11025
-
11026
- error(typePredicateNode.parameterName,
11027
- Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
11028
- typePredicate.parameterName);
11029
- hasReportedError = true;
11030
- break;
11031
- }
11032
- else if (element.name.kind === SyntaxKind.ArrayBindingPattern ||
11033
- element.name.kind === SyntaxKind.ObjectBindingPattern) {
11034
-
11035
- checkBindingPattern(<BindingPattern>element.name);
11036
- }
11037
- }
11038
- })(<BindingPattern>param.name);
11039
- }
11040
- }
11041
- if (!hasReportedError) {
11042
- error(typePredicateNode.parameterName,
11043
- Diagnostics.Cannot_find_parameter_0,
11044
- typePredicate.parameterName);
11045
- }
11046
- }
11047
- }
11048
- else {
11049
- error(typePredicateNode,
11050
- Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
11051
- }
11052
- }
11053
- else {
11054
- checkSourceElement(node.type);
11055
- }
11077
+ checkSourceElement(node.type);
11078
+ if (node.type && node.type.kind === SyntaxKind.TypePredicate) {
11079
+
11056
11080
}
11057
11081
11058
11082
if (produceDiagnostics) {
@@ -14195,12 +14219,6 @@ namespace ts {
14195
14219
74C1
}
14196
14220
}
14197
14221
14198
- function checkTypePredicate(node: TypePredicateNode) {
14199
- if (!isInLegalTypePredicatePosition(node)) {
14200
- error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
14201
- }
14202
- }
14203
-
14204
14222
function checkSourceElement(node: Node): void {
14205
14223
if (!node) {
14206
14224
return;
0 commit comments