【问题标题】:Why doesn't this code cause a TypeScript type error?为什么这段代码不会导致 TypeScript 类型错误?
【发布时间】:2015-08-17 21:45:35
【问题描述】:

接口定义如下:

interface IRemoteService {
  createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>>;
}

interface ICreateResponse<T> {
  createdId: T;
}

为什么下面的代码不会导致 Typescript 编译错误?

class RemoteServiceMock implements IRemoteService {
  public static $inject = ["$q"];

  constructor(private $q: ng.IQService){
  }

  createRecord(record: RecordType): ng.IPromise<ICreateResponse<string>> {
    return this.$q.when({});
  }
}

$q.when 的类型是when&lt;T&gt;(value: T): IPromise&lt;T&gt;

【问题讨论】:

  • 是...“{}”属于“Any”类型,因为“Any”不是类型...因为它是“任何类型”。
  • 肯定 {} 是 Object 类型的吗?
  • 是的...但是任何类型都可以是“any”类型。就像说...“任何东西”... ...显然哪个“对象”也满足...一样。
  • 我的意思是“是否像 {} 一样对待 {}”,但您是对的,这可能不清楚。已编辑。
  • ICreateResponse的定义是什么?

标签: angularjs typescript typescript1.5


【解决方案1】:

这是根据规范。这是您的示例简化:

interface A{
}
interface B {
  createdId: string;
}

var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // No error

如果 A 是 B 的子类型或 B 是 A 的子类型,则允许此赋值。如果不是这种情况,您将收到如下所示的错误:

interface A {
  breakTypeCompat: number;
}
interface B {
  createdId: string;
}

var foo:ng.IPromise<A>;
var bar:ng.IPromise<B>;
bar = foo; // Error

原因是函数参数的双变量兼容性。请参阅此链接了解文档 + 原因:https://github.com/Microsoft/TypeScript/wiki/Type-Compatibility#function-argument-bivariance

详情

背景

接口的类型兼容性取决于您如何使用它们。例如。以下不是错误:

interface IPromise<T>{  
}

interface A{
}
interface B {
  createdId: string;
}

var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // No error

但是如果IPromise在哪里使用类型参数作为成员就会出错:

interface IPromise<T>{
    member:T    
}

interface A{    
}
interface B {
  createdId: string;
}

var foo:IPromise<A>;
var bar:IPromise<B>;
bar = foo; // Error

因此

在实际的 Promise 定义中,我们有类似的内容:

interface IPromise<T> {
    then(successCallback: (promiseValue: T) => any): any;
}

interface A {
}
interface B {
    createdId: string;
}

var foo: IPromise<A>;
var bar: IPromise<B>;
bar = foo; // No Error

由于我们使用T 作为函数的参数,AB 将通过双变量进行类型检查。因此,如果 A 是 B 的子集或 B 是 A 的子集,它们是兼容的。

【讨论】:

  • 上面的例子确实有效。很抱歉在问题之上提出问题,但为什么允许这样做? A 没有实现 B,所以这似乎会极大地损害接口成员的有用性。
  • 谢谢!现在更有意义了。 :)
【解决方案2】:

我不确定您为什么没有收到错误消息,但我确实有关于如何收到警告的建议。根据 angular.d.ts when 是这样定义的:

when<T>(value: IPromise<T>): IPromise<T>;
when<T>(value: T): IPromise<T>;
when(): IPromise<void>;

因此,如果您想使用when 输入更多内容,请使用:

return this.$q.when<ICreateResponse<string>>({});

【讨论】:

  • 谢谢,这确实给了我一个很棒的错误。
猜你喜欢
  • 1970-01-01
  • 2011-03-16
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多