Skip to content

Type error when using socket.timeout.emitWithAck #4925

Closed

Description

@GStarP

Describe the bug
When using socket.timeout.emitWithAck, even if you set EmitEvents correctly, the return type will be a wrong any.

To Reproduce

no need for server participation.

Server

Socket.IO client version: 4.7.4

Client

import type { Socket } from 'socket.io-client'

type MySocket = Socket<DefaultEventsMap, EmitEvents>
type DefaultEventsMap = {
  [event: string]: (...args: any[]) => void
}
type EmitEvents = {
  hello: (cb: (val: number) => void) => void
}

const socket = {} as MySocket
const r1 = socket.emitWithAck('hello') // Promise<number>
const r2 = socket.timeout(1000).emitWithAck('hello') // Promise<any>

Expected behavior
r2 should also be inferred as Promise<number>.

Platform:

  • Typescript version: 5.3.3

Additional context

The return type of emitWithAck is from Promise<FirstArg<Last<EventParams<EmitEvents, Ev>>>>, which picks the first argument of cb. However, timeout uses DecorateAcknowledgements then PrependTimeoutError, which prepend a Error type param to cb, so this FirstArg will focus on the error instead of the real return value.

Maybe replace FirstArg with a type LastArg<T> = T extends (...args: infer Args) => any ? Args extends [] ? never : Args extends [...infer _, infer Last] ? Last : never : never; will solve this issue? I'm not so familiar with the js logic, so just a hypothesis.

By the way, I have found the same problem in #4813 , it can be solved by using socket options ackTimeout in the client side (I have already adopted this solution). But I think it's better if this problem can be solved completely.

Activity

  1. added
    to triageWaiting to be triaged by a member of the team
    on Jan 18, 2024
  2. darrachequesne commented on Jan 22, 2024

    @darrachequesne
    Member

    You are right, we need to apply the same changes on the client side: #4817

  3. added
    bugSomething isn't working
    and removed
    to triageWaiting to be triaged by a member of the team
    on Jan 22, 2024
  4. GStarP commented on Jan 22, 2024

    @GStarP
    Author

    Oh sorry, I should post this issue in the client side repo.

    Thanks for answering, I will close this issue and look forward to the new version client.

  5. DudaGod commented on Apr 11, 2024

    @DudaGod

    You are right, we need to apply the same changes on the client side: #4817

    Hello. Do I understand correctly that this is not supported on the client yet? When can I expect a new version?

    Thanks.

  6. MiloWang2048 commented on Jun 29, 2024

    @MiloWang2048

    I can reproduce this error with socket.io version 4.7.5, on server side, with or without timeout() call.

    await targetUserSocket.emitWithAck("PrivateMessage", content);

    Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345)

    But socket.emit() works just fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions