-
Notifications
You must be signed in to change notification settings - Fork 367
Description
There are some generic methods that accept parameter named type, which type defines types of request handler, including parameter types and result type.
Here is an example of such method:
onRequest<P, R, PR, E, RO>(type: ProtocolRequestType<P, R, PR, E, RO>, handler: RequestHandler<P, R, E>): DisposableTypeScript compiler infers generic arguments from both the type and handler parameters. This can result in the inferred types being wider than what is allowed by ProtocolRequestType.
For example, the following code compiles but should not, because the return type of the handler, ls.Hover | undefined | string, is not assignable to the type Hover | null specified in ls.HoverRequest.type.
const connection: Connection = null as any;
const handler: (params: HoverParams) => Promise<Hover | undefined | string> = null as any;
connection.onRequest(HoverRequest.type, handler); // no errorIf we wrap type of the handler parameter in NoInfer, TypeScript will not infer onRequest method generic arguments from handler parameter and will correctly report an error.
Here is another example:
const params: HoverParams | string = null as any;
await connection.sendRequest(HoverRequest.type, params); // no errorIt’s also necessary to adjust the HandlerResult type to allow returning undefined wherever returning null is permitted, since the library code automatically replaces all undefined values with null.
This can be done as follows:
export type HandlerResult<R, E, R_ = R extends null ? (R | undefined) : R> = R_ | ResponseError<E> | Thenable<R_> | Thenable<ResponseError<E>> | Thenable<R_ | ResponseError<E>>After applying these changes locally, I was able to find several incorrect return types in my request handlers.
If you agree with the proposed changes, I would like to make a PR implementing them.