@@ -4,11 +4,13 @@ import {
44 CallExpression ,
55 createPrinterWithRemoveComments ,
66 Debug ,
7+ ElementFlags ,
78 EmitHint ,
89 EnumMember ,
910 equateStringsCaseInsensitive ,
1011 Expression ,
1112 findChildOfKind ,
13+ findIndex ,
1214 forEachChild ,
1315 FunctionDeclaration ,
1416 FunctionExpression ,
@@ -44,6 +46,7 @@ import {
4446 isParameterDeclaration ,
4547 isPropertyAccessExpression ,
4648 isPropertyDeclaration ,
49+ isSpreadElement ,
4750 isTypeNode ,
4851 isVarConst ,
4952 isVariableDeclaration ,
@@ -61,6 +64,7 @@ import {
6164 SymbolFlags ,
6265 SyntaxKind ,
6366 textSpanIntersectsWith ,
67+ TupleTypeReference ,
6468 Type ,
6569 TypeFormatFlags ,
6670 unescapeLeadingUnderscores ,
@@ -226,14 +230,31 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
226230 return ;
227231 }
228232
229- for ( let i = 0 ; i < args . length ; ++ i ) {
230- const originalArg = args [ i ] ;
233+ let signatureParamPos = 0 ;
234+ for ( const originalArg of args ) {
231235 const arg = skipParentheses ( originalArg ) ;
232236 if ( shouldShowLiteralParameterNameHintsOnly ( preferences ) && ! isHintableLiteral ( arg ) ) {
233237 continue ;
234238 }
235239
236- const identifierNameInfo = checker . getParameterIdentifierNameAtPosition ( signature , i ) ;
240+ let spreadArgs = 0 ;
241+ if ( isSpreadElement ( arg ) ) {
242+ const spreadType = checker . getTypeAtLocation ( arg . expression ) ;
243+ if ( checker . isTupleType ( spreadType ) ) {
244+ const { elementFlags, fixedLength } = ( spreadType as TupleTypeReference ) . target ;
245+ if ( fixedLength === 0 ) {
246+ continue ;
247+ }
248+ const firstOptionalIndex = findIndex ( elementFlags , f => ! ( f & ElementFlags . Required ) ) ;
249+ const requiredArgs = firstOptionalIndex < 0 ? fixedLength : firstOptionalIndex ;
250+ if ( requiredArgs > 0 ) {
251+ spreadArgs = firstOptionalIndex < 0 ? fixedLength : firstOptionalIndex ;
252+ }
253+ }
254+ }
255+
256+ const identifierNameInfo = checker . getParameterIdentifierNameAtPosition ( signature , signatureParamPos ) ;
257+ signatureParamPos = signatureParamPos + ( spreadArgs || 1 ) ;
237258 if ( identifierNameInfo ) {
238259 const [ parameterName , isFirstVariadicArgument ] = identifierNameInfo ;
239260 const isParameterNameNotSameAsArgument = preferences . includeInlayParameterNameHintsWhenArgumentMatchesName || ! identifierOrAccessExpressionPostfixMatchesParameterName ( arg , parameterName ) ;
0 commit comments