通用函数约束?它们是否会导致编译时错误

时间:2018-01-12 18:02:07

标签: typescript

我希望以下代码抛出编译类型错误,但它没有。

interface Service {
}

abstract class TestService implements Service {
}

class TestServiceImpl extends TestService {

}

class Blah {

}

function getService<T extends Service>(service: T): string {
    return 'hello';
}

let m = getService( Blah );

当我期望T扩展Service约束来阻止它时,编译器似乎非常高兴有一个类型没有扩展Service传入getService。有什么想法吗?

修改

因此,将getService更改为具有引用其参数的正确主体没有任何区别。

更改服务界面以使其中包含某些内容,有点意义,但与我以前在其他语言中使用的内容不同。

现在问题是以下代码有错误但不是我预期的

interface Service {
    doSomething(): number;
}

abstract class TestService implements Service {
    public doSomething(): number {
        return 1;
    }
}

class TestServiceImpl extends TestService {
    public doSomethingElse(): void {
        //
    }
}

function getService<T extends Service>(service: T): string {
    return (<any>service).name;
}

let m = getService( TestService );

我现在收到错误:

  

错误TS2345:类型&#39;类型TestService&#39;的参数不能分配给&#39;服务&#39;类型的参数。     物业&#39; doSomething&#39;在类型&#39; typeof TestService&#39;中缺失。   让m = getService(TestService);

显然,TestService实现了服务?

显然这里有点笨蛋

1 个答案:

答案 0 :(得分:2)

getService(Blah)实际上是在传递声明 Blah,我认为它实际上只是一个函数。我相信你的意思是通过getService(new Blah)

在TypeScript中,不必声明类型以相互扩展。它只是检查接口是否符合。由于Service没有任何属性,因此几乎任何东西都符合它。您甚至可以执行getService(1)getService(false)之类的操作,但不会导致TypeScript错误。

作为另一个例子,您可以:let blah: Service = new Blah(); getService(blah)。 TypeScript为你做了强制。

如果Service具有属性,则Blah必须与这些属性匹配:

interface Service { a: string; }
class Blah { }
getService(new Blah()); // error - Type 'Blah' is not assignable to type 'Service'
class BetterBlah { a: string; }
getService(new BetterBlah()); // works -- interfaces conform

也就是说TypeScript中的接口是 advisory 。我认为这与JavaScript和对象变量声明的互操作性有关。例如,使用上面的Service类型,您也可以执行以下操作:

getService({ a: 'value' });