Kir
Kir

Reputation: 3052

Typescript typeguards for generics not enforced

interface Foo {
    bar() : Promise<string>;
}

class MyFoo implements Foo {
    bar() : string {
        return "";
    }
}

class MyFoo2 implements Foo {
    bar() : Promise<number> {
        return new Promise<number>(null);
    }
}

Shouldn't each of the two implementations above cause an error?

What I can tell is that TypeScript seems to check the members of the return type and not the declared type. But is there a way to declare this interface in a way that requires the implementations to return the correct type?

edit: It seems that because the es6 interface Promise is defined with members like then() : Promise<T>, but nothing like foo(): T, the type checking doesn't work. If I simulate this with my custom generic interface, it will properly error if the interface contains a member of type T, but not of a generic of type T

Upvotes: 1

Views: 70

Answers (1)

Szabolcs D&#233;zsi
Szabolcs D&#233;zsi

Reputation: 8843

This is a bug in the current stable version of TypeScript.

Sources:

It has already been fixed and will be included in a future version (2.1).

I tried it myself too:

D:\Practice\TypeScript\ts-test>npm install -g typescript
C:\Users\dezsi\AppData\Roaming\npm\tsc -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\dezsi\AppData\Roaming\npm\tsserver -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
C:\Users\dezsi\AppData\Roaming\npm
└── [email protected]


D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --version
Version 2.0.10

D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --target ES6 app.ts

D:\Practice\TypeScript\ts-test>npm install -g typescript@next
C:\Users\dezsi\AppData\Roaming\npm\tsc -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsc
C:\Users\dezsi\AppData\Roaming\npm\tsserver -> C:\Users\dezsi\AppData\Roaming\npm\node_modules\typescript\bin\tsserver
C:\Users\dezsi\AppData\Roaming\npm
└── [email protected]



D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --version
Version 2.2.0-dev.20161122

D:\Practice\TypeScript\ts-test>C:\Users\dezsi\AppData\Roaming\npm\tsc.cmd --target ES6 app.ts
app.ts(5,7): error TS2420: Class 'MyFoo2' incorrectly implements interface 'Foo'.
  Types of property 'bar' are incompatible.
    Type '() => Promise<string>' is not assignable to type '() => Promise<number>'.
      Type 'Promise<string>' is not assignable to type 'Promise<number>'.
        Type 'string' is not assignable to type 'number'.

Here you can see that trying with version 2.0.10 doesn't give me an error, while the latest 2.2.0-dev.20161122 correctly reports Type 'string' is not assignable to type 'number'.

Upvotes: 3

Related Questions