Skip to content

Type error when using socket.timeout.emitWithAck #4925

Closed
@GStarP

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.

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