@@ -459,7 +459,7 @@ export class Parser extends DiagnosticEmitter {
459459 if ( ! suppressErrors ) {
460460 this . error (
461461 DiagnosticCode . _0_expected ,
462- tn . range ( tn . pos ) , "} "
462+ tn . range ( tn . pos ) , ") "
463463 ) ;
464464 }
465465 return null ;
@@ -620,6 +620,8 @@ export class Parser extends DiagnosticEmitter {
620620 var parameters : ParameterNode [ ] | null = null ;
621621 var thisType : NamedTypeNode | null = null ;
622622 var isSignature : bool = false ;
623+ var firstParamNameNoType : IdentifierExpression | null = null ;
624+ var firstParamKind : ParameterKind = ParameterKind . DEFAULT ;
623625
624626 if ( tn . skip ( Token . CLOSEPAREN ) ) {
625627 isSignature = true ;
@@ -684,11 +686,29 @@ export class Parser extends DiagnosticEmitter {
684686 if ( ! parameters ) parameters = [ param ] ;
685687 else parameters . push ( param ) ;
686688 } else {
689+ if ( ! isSignature ) {
690+ if ( tn . peek ( ) == Token . COMMA ) {
691+ isSignature = true ;
692+ tn . discard ( state ) ;
693+ }
694+ }
687695 if ( isSignature ) {
696+ let param = new ParameterNode ( ) ;
697+ param . parameterKind = kind ;
698+ param . name = name ;
699+ param . type = Node . createOmittedType ( tn . range ( ) . atEnd ) ;
700+ if ( ! parameters ) parameters = [ param ] ;
701+ else parameters . push ( param ) ;
688702 this . error (
689703 DiagnosticCode . Type_expected ,
690- tn . range ( )
704+ param . type . range
691705 ) ; // recoverable
706+ } else if ( ! parameters ) {
707+ // on '(' Identifier ^',' we don't yet know whether this is a
708+ // parenthesized or a function type, hence we have to delay the
709+ // respective diagnostic until we know for sure.
710+ firstParamNameNoType = name ;
711+ firstParamKind = kind ;
692712 }
693713 }
694714 } else {
@@ -720,8 +740,22 @@ export class Parser extends DiagnosticEmitter {
720740
721741 var returnType : TypeNode | null ;
722742 if ( tn . skip ( Token . EQUALS_GREATERTHAN ) ) {
723- isSignature = true ;
724- tn . discard ( state ) ;
743+ if ( ! isSignature ) {
744+ isSignature = true ;
745+ tn . discard ( state ) ;
746+ if ( firstParamNameNoType ) { // now we know
747+ let param = new ParameterNode ( ) ;
748+ param . parameterKind = firstParamKind ;
749+ param . name = firstParamNameNoType ;
750+ param . type = Node . createOmittedType ( firstParamNameNoType . range . atEnd ) ;
751+ if ( ! parameters ) parameters = [ param ] ;
752+ else parameters . push ( param ) ;
753+ this . error (
754+ DiagnosticCode . Type_expected ,
755+ param . type . range
756+ ) ; // recoverable
757+ }
758+ }
725759 returnType = this . parseType ( tn ) ;
726760 if ( ! returnType ) {
727761 this . tryParseSignatureIsSignature = isSignature ;
0 commit comments