TS2417 when overriding static method

1.1k Views Asked by At

Edit - updated code to reflect comments

I'm upgrading some old code from TS 2.2.1 to TS 2.5.2, and hitting a compilation issue. When trying to compile the following code:

export interface IFuture<TResult> {
    done(callback: (result: TResult) => void): IFuture<TResult>;
}
export interface IVoidFuture extends IFuture<void | any> {
    done(callback: (result?: void) => void): IVoidFuture;
}

export class Future<TResult> implements IFuture<TResult>{
    public static createResolved<TResult>(result?: TResult): IFuture<TResult> {
        let asyncResult: Future<TResult> = new Future<TResult>();
        return asyncResult;
    }


    public done(callback: (result: TResult) => void): Future<TResult> {
        return this;
    }
}

export class VoidFuture extends Future<void> implements IVoidFuture  {
    private static _resolvedFuture: IVoidFuture;

    public static createResolved(result?: void): IFuture<void> {
        if (!VoidFuture._resolvedFuture) {
            VoidFuture._resolvedFuture = Future.createResolved<void>();
        }
        return VoidFuture._resolvedFuture;
    }

    public done(callback: (result?: void) => void): IVoidFuture {
        return super.done(callback);
    }
}

I get the following error:

file.ts(20,14): error TS2417: Class static side 'typeof VoidFuture' incorrectly extends base class static side 'typeof Future'.
  Types of property 'createResolved' are incompatible.
    Type '(result?: void) => IVoidFuture' is not assignable to type '<TResult>(result?: TResult) => IFuture<TResult>'.
      Types of parameters 'result' and 'result' are incompatible.
        Type 'TResult' is not assignable to type 'void'.
1

There are 1 best solutions below

0
On

The VoidFuture class should Implement the interface as it is written. Future does not match the expected Future. Maybe you want Future?

export interface IFuture<TResult> {
   done(callback: (result: TResult) => void): IFuture<TResult>;
}
export interface IVoidFuture extends IFuture<void | any> {
    done(callback: (result?: void) => void): IVoidFuture;
}

export class Future<TResult> {
    public static createResolved<TResult>(result?: TResult): IFuture<TResult> {
        let asyncResult: Future<TResult> = new Future<TResult>();
        return asyncResult;
    }
    public done(callback: (result: TResult) => void): Future<TResult> {
        return this;
    }
}
export class VoidFuture implements Future<TResult>  {//needs to match interface definition
    private static _resolvedFuture: IVoidFuture;
    public static createResolved(result?: void): IVoidFuture {
        if (!VoidFuture._resolvedFuture) {
            VoidFuture._resolvedFuture = Future.createResolved<void>();
        }
       return VoidFuture._resolvedFuture;
    }

    public done(callback: (result?: void) => void): IVoidFuture {
         return super.done(callback);
    }
}