1

I have a class which implements an interface. Both define a method which takes in a generic and outputs an Array of the same type as the generic. I'm getting a weird error about inconsistencies between the class and the interface and I'm not sure how to solve it. Here is some sample code:

class Random implements IRandom {
    generateArray<T>(method: string): Array<T>;
    generateArray<T>(Constructor: new () => T): Array<T>;
    generateArray(method: any) {
        return new Array<any>();
    }
}

interface IRandom {
    generateArray<T>(method: string): Array<T>;
    generateArray<T>(Constructor: new () => T): Array<T>;
}

Here is an error snippet for the above code:

Class Random declares interface IRandom but does not implement it:
    Types of property 'generateArray' of types 'Random' and 'IRandom' are incompatible:
        Call signatures of types '{ <T>(method: string): T[]; <T>(Constructor: new() => T): T[]; }' and '{ <T>(method: string): T[]; <T>(Constructor: new() => T): T[]; }' are incompatible:
            Types of property 'concat' of types '{}[]' and 'T[]' are incompatible:
                Call signatures of types '{ <U extends T[]>(...items: U[]): {}[]; (...items: {}[]): {}[]; }' and '{ <U extends T[]>(...items: U[]): T[]; (...items: T[]): T[]; }' are incompatible:
                    Types of property 'pop' of types '{}[]' and 'T[]' are incompatible:
                        Call signatures of types '() => {}' and '() => T' are incompatible.

Has anyone encountered this error? Is there a way to fix it?

4
  • Your code compiles for me. Do you have the latest version of typescript installed? Commented Feb 6, 2014 at 4:32
  • I'm using the plugin for VS 2013, running v0.9.5. Is there a newer version? Perhaps I should reinstall. Commented Feb 6, 2014 at 5:02
  • possible duplicate of Generic interface declaration not working as-is on typescript 0.9.5 Commented Feb 6, 2014 at 5:08
  • It's a bug. It doesn't work if you use the current version available on the typescript playground. Commented Feb 6, 2014 at 5:09

1 Answer 1

1

You have stumbled across a bug - but it has been fixed (so will come out with the next release)...

In the meantime, there are two workarounds available...

Make The Interface And Class Generic (rather than the method).

interface IRandom<T> {
    generateArray(method: string): T[];
    generateArray(Constructor: new () => T): T[];
}

class Random<T> implements IRandom<T> {
    generateArray(method: string): T[];
    generateArray(Constructor: new () => T): T[];
    generateArray(method: any) {
        return new Array<any>();
    }
}

Or define the interface using the class (as a temporary measure). This would allow you to turn the tables when the bug is fixed by removing the extends Random, adding back in the interface body and putting back the implements IRandom.

interface IRandom extends Random {

}

class Random {
    generateArray<T>(method: string): Array<T>;
    generateArray<T>(Constructor: new () => T): Array<T>;
    generateArray(method: any) {
        return new Array<any>();
    }
}

All of the calling code would be unaware of the deception:

function paramIsInterface(param: IRandom) {
    // Stuff
}

var r = new Random();

paramIsInterface(r); // Accepts Random is an IRandom...
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I guess I'll have to go with option 2 for the time being.

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.