在TypeScript中键入约束错误

时间:2013-11-16 19:00:27

标签: typescript

我遇到过一个问题,TypeScript编译器抱怨类型约束错误,但一切看起来都不正确,所以我似乎无法弄清楚原因。

这是一个简化的例子:

// Base module
module Base {
   export interface Scope<TConfiguration> {
      configuration: TConfiguration;
   }

   export class Controller<TScope extends Scope<TConfiguration>, TConfiguration> {
      $scope: TScope;
   }    
}

// Implementation module
module Impl {
   export interface Configuration {
   }

   export interface Scope extends Base.Scope<Configuration> {
   }

   export class Controller extends Base.Controller<Scope, Configuration> {
   }
}

如果您将代码粘贴到http://www.typescriptlang.org/Playground/的编辑器中,您应该会看到我收到的错误:

Type 'Impl.Scope' does not satisfy the constraint 'Base.Scope<TConfiguration>' for type parameter 'TScope extends Base.Scope<TConfiguration>'.

关于我做错的任何想法?谢谢!

2 个答案:

答案 0 :(得分:1)

你的代码很好;这是编译器中的一个错误。在即将发布的0.9.5版本中,此代码编译时没有错误。

答案 1 :(得分:0)

编译器似乎对在TScope类型参数的约束内使用TConfiguration类型参数感到不满。

这是一个编译的例子 - 不使用约束中的第二个类型参数。

// Base module
module Base {
   export interface Scope<TConfiguration> {
      configuration: TConfiguration;
   }

   export class Controller<TScope extends Scope<Impl.Configuration>, TConfiguration> {
      $scope: TScope;
   }    
}

// Implementation module
module Impl {
   export interface Configuration {
   }

   export interface Scope extends Base.Scope<Configuration> {
   }

   export class Controller extends Base.Controller<Scope, Configuration> {
   }
}

可能的解决方案......

你的Scope是一个接口,所以也许你真的不需要指定确切的“范围类型” - 只要它是Scope ...你的约束只允许你无论如何都要在Scope上调用属性和函数......

// Base module
module Base {
   export interface Scope<TConfiguration> {
      configuration: TConfiguration;
   }

   export class Controller<TConfiguration> {
      $scope: Scope<TConfiguration>;
   }    
}

可以在TypeScript中使用泛型函数来使用传递给封闭泛型类的类型参数...这意味着你可以这样做:

// Base module
module Base {
   export interface Scope<TConfiguration> {
      configuration: TConfiguration;
   }

   export class Controller<TConfiguration> {
      $scope: Scope<TConfiguration>;

      addScope<TScope extends Scope<TConfiguration>>(scope: TScope) {
          this.$scope = scope;
      }
   }    
}

// Implementation module
module Impl {
   export interface Configuration {
   }

   export interface Scope extends Base.Scope<Configuration> {
   }

   export class Controller extends Base.Controller<Configuration> {
   }
}