X Tutup
Skip to content

Use NoInfer for better typing#1691

Merged
dbaeumer merged 8 commits intomicrosoft:mainfrom
itrapashko:no-infer
Dec 17, 2025
Merged

Use NoInfer for better typing#1691
dbaeumer merged 8 commits intomicrosoft:mainfrom
itrapashko:no-infer

Conversation

@itrapashko
Copy link
Contributor

@itrapashko itrapashko commented Nov 20, 2025

Fixes #1685

After adding NoInfer to types of parameters, several compilation errors appeared in the Connection interface in the methods that register request handlers for DocumentLinkResolve, DocumentColor, and ColorPresentation. The reason for them is that the return type of the request specified in those methods did not match the return type specified in the corresponding type variables and in the protocol specification. The return type does not allow null and undefined, so I removed those from the types.

@itrapashko
Copy link
Contributor Author

@microsoft-github-policy-service agree

*
* @param handler The corresponding handler.
*/
onDocumentColor(handler: ServerRequestHandler<DocumentColorParams, ColorInformation[] | undefined | null, ColorInformation[], void>): Disposable;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove undefined and null here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this is that result type specified here does not match result type, specified in DocumentColorRequest.type:

export const type = new ProtocolRequestType<DocumentColorParams, ColorInformation[], ColorInformation[], void, DocumentColorRegistrationOptions>(method);

As you can see, result type does not allow null values. We should either add null to DocumentColorRequest.type or remove null and undefined from Connection.onDocumentColor. Otherwise there will be a compilation error on line 1629. I have chosen the second option because it matches protocol specification.

onDocumentColor: (handler) => connection.onRequest(DocumentColorRequest.type, (params, cancel) => {
return handler(params, cancel, attachWorkDone(connection, params), attachPartialResult(connection, params));
}),

Same with onColorPresentation.

* @param handler The corresponding handler.
*/
onColorPresentation(handler: ServerRequestHandler<ColorPresentationParams, ColorPresentation[] | undefined | null, ColorPresentation[], void>): Disposable;
onColorPresentation(handler: ServerRequestHandler<ColorPresentationParams, ColorPresentation[], ColorPresentation[], void>): Disposable;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answered above.

@dbaeumer dbaeumer added the feature-request Request for new features or functionality label Dec 8, 2025
@dbaeumer dbaeumer added this to the December / January 2026 milestone Dec 8, 2025
@itrapashko itrapashko requested a review from dbaeumer December 9, 2025 10:28
@dbaeumer
Copy link
Member

To keep things consistent with other requests that can return an array I would suggest the following:

  • keep undefined | null on the handler registration. The server implementation converts undefined to null for the wire.
  • change the type definition to include null. undefined needs to be left out since it is not a valid JSON type.

}

export type HandlerResult<R, E, _R = R extends null ? (R | undefined) : R> = _R | ResponseError<E> | Thenable<_R> | Thenable<ResponseError<E>> | Thenable<_R | ResponseError<E>>;
export type HandlerResult<R, E, _R = R extends null ? (R | undefined | void) : R> = _R | ResponseError<E> | Thenable<_R> | Thenable<ResponseError<E>> | Thenable<_R | ResponseError<E>>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it possible to pass handlers that return void if null is acceptable, because handlers that return void will return undefined, and undefined will be automatically converted to null.

@itrapashko
Copy link
Contributor Author

itrapashko commented Dec 17, 2025

As suggested, I added null to result type of DocumentColorRequest and ColorPresentationRequest - requests, that return arrays.

I've also noticed that if parameter type allows null, it should be possible to pass undefined. So I added RequestParam type, and wrapped all parameter types in it. Here is how it looks like:

export type RequestParam<P> = P extends null ? P | undefined : P;
// ...
sendRequest<P, R, PR, E, RO>(type: ProtocolRequestType<P, R, PR, E, RO>, params: NoInfer<RequestParam<P>>, token?: CancellationToken): Promise<R>;

This change is necessary because before using NoInfer it was possible to pass undefined due to some incorrect inferring, and with stronger typing it became impossible.

Let me know what you think about this change.

}
}

export type RequestParam<P> = P extends null ? P | undefined : P;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RequestParam type is declared here.

@dbaeumer
Copy link
Member

I like the change of the RequestParam<P> = P extends null ? P | undefined : P;

@dbaeumer
Copy link
Member

/AzurePipelines run

@dbaeumer dbaeumer closed this Dec 17, 2025
@dbaeumer dbaeumer reopened this Dec 17, 2025
@dbaeumer
Copy link
Member

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@dbaeumer dbaeumer merged commit 1baf163 into microsoft:main Dec 17, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature-request Request for new features or functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using NoInfer for better typing

3 participants

X Tutup