0

I run a method that eventually adds a an object to the array where one of the properties extends IServerResponse.

activeRequests: Array<ActiveRequest>;

interface ActiveRequest {
    transactionId: string;
    resolve: <T extends IServerResponse>(value: T) => void;
    reject: (reason: Error) => void;
    timer: NodeJS.Timeout;
    progress: undefined | ((progress: Progress) => void);
}

// Example request start
export interface GetActiveProjectServerResponse extends IServerResponse {
    type: 'response';
    cmd: 'otii_get_active_project';
    data: {
        project_id: number;
    }
}

async run(): Promise<GetActiveProjectResponse> {
    let serverResponse = await new Promise<GetActiveProjectServerResponse>((resolve, reject) => {
        this.connection.push(
            this.requestBody, 
            this.transactionId, 
            this.maxTime, 
            resolve as (value: GetActiveProjectServerResponse) => void, 
            reject
        );
    });
}
// Example request end

public push<T extends IServerResponse>(
    requestBody: any,
    transactionId: string,
    maxTime: number,
    resolve: (value: T) => void,
    reject: (reason: Error) => void,
    progress?: (progress: Progress) => void
): void {
            this.activeRequests.push({
        transactionId,
        resolve,
        reject,
        timer,
        progress
    });
}

public onMessage(event: { data: WebSocket.Data }): void {
    ...
    let req = this.activeRequests.find(request => {
        return request.transactionId === transactionId;
    });

    req.resolve(serverMessage);
}

But I get an error on the line this.activeRequests.push(...):

[ts]
Argument of type '{ transactionId: string; resolve: (value: T) => void; reject: (reason: Error) => void; timer: Timeout; progress: ((progress: number) => void) | undefined; }' is not assignable to parameter of type 'ActiveRequest'.
  Types of property 'resolve' are incompatible.
    Type '(value: T) => void' is not assignable to type '<T extends IServerResponse>(value: T) => void'.
      Types of parameters 'value' and 'value' are incompatible.
        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
          Type 'IServerResponse' is not assignable to type 'T'.

I don't understand this. Why is T not compatible? I pass around the same resolve function with the same limitation to type.

How can I fix this problem?

1 Answer 1

1

You didn't include the line that causes the error, but the problem is probably that ActiveRequest "promises" to handle any T that extends IServerResponse, but you try to create one that only handles GetActiveProjectServerResponse. You can fix it like this:

interface ActiveRequest<TResponse as IServerResponse> {
    transactionId: string;
    resolve: (value: TResponse) => void;
    reject: (reason: Error) => void;
    timer: NodeJS.Timeout;
    progress: undefined | ((progress: Progress) => void);
}
activeRequests: Array<ActiveRequest<any>>;

...
const req: ActiveRequest<GetActiveProjectServerResponse> = {
   ...
   resolve: (value: GetActiveProjectServerResponse) => {},
}
activeRequests.push(req)

TypeScript won't check that what your request gets is actually GetActiveProjectServerResponse but it doesn't matter because serverMessage is probably untyped anyway.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.