为什么没有强制转换就转换为更具体的类型

时间:2016-06-20 10:08:49

标签: typescript

在尝试找出将http调用的json响应转换为TypeScript类/接口的最佳方法时,我在stack overflow上找到了这个代码snippit。

getTeachers(): Observable<Teacher> {
  return this.http.get('someUrl')
    .map((res: Response) => res.json())
}

它看起来不错,但我不明白它是如何工作的。

  • 为什么没有强制语法将any类型的res.json()转换为更具体的Teacher类型?
  • 为什么Teacher建议使用TypeScript interface而不是TypeScript class

2 个答案:

答案 0 :(得分:0)

如果你看一下Observable的签名:

export declare class Observable<T> implements Subscribable<T> {...}

你可以看到它需要参数 T SomeThing<SomeType>被称为 泛型 并引用TypeScript Hadnbook,如果你看一下通用身份函数:

  function identity(arg: any): any {
    return arg;
  }
  

虽然使用任何肯定是通用的,因为它将接受arg类型的任何和所有类型,但实际上我们正在丢失函数返回时该类型的信息。如果我们传入了一个数字,我们唯一的信息就是可以返回 任何 类型。

     

相反,我们需要一种捕获参数类型的方法,以便我们也可以使用它来表示返回的内容。在这里,我们将使用 类型变量 ,这是一种特殊的变量,适用于类型而不是值。

  function identity<T>(arg: T): T {
    return arg;
  }

如果您不关心此功能返回的内容(或者您不知道),则可以定义getTeachers(): any {}。它会起作用,但是假设从现在开始升级你的应用程序几个月后,你就会制作一个漂亮的新组件,它需要调用getTeachers()。它会回归什么?的不限即可。凉。 = digs-through-months-old-code = 重复N次(;

但是既然你知道函数是什么(返回http.method,它是一个Observable),你可以写getTeachers(): Observable<any>{}。 ...闪亮的新成分;致电getTeachers()。它会回归什么?的可观察即可。很好,我可以订阅它,并获得任何。好的,我可以用...

在大多数情况下/例子中,这已经足够了。但你可以更具体。 如果您知道this.http.get('someUrl')返回的内容(让我们在响应正文中说出它是一个JSON对象,请使用标题&#39;内容类型&#39;设置为&#39; application / json&#39; - 你使用Respone.json()来提取它,你可以写getTeachers(): Observable<{}>{}。现在我们知道它是对象

最后,如果你知道该对象与接口教师具有相同的属性,你可以像这样定义你的函数:

  getTeachers(): Observable<Teacher> {}
  

为什么没有强制语法将泛型任何类型的res.json()转换为更具体的类型教师?

这里没有转换,数据保持不变。您只是提供&#34;描述&#34;通过声明它是特定类型的数据。根据您了解的信息。没有魔力(:。

  

为什么建议Teacher成为TypeScript接口而不是TypeScript类?

在此上下文中,Teacher可以是类或接口。这并不重要,TypeScript将从类或接口读取信息。如果您在任何其他上下文中都没有使用Teacher,那么您可以创建一个界面(它不会编译为JavaScript,因此代码更少)。如果您在其他地方使用它,例如,如果您需要Teacher的实例:

  let new_guy = new Teacher();

然后你应该将教师宣布为一个班级。

答案 1 :(得分:0)

我将根据@ Sasxa的回答和我通过其他渠道收到的输入回答我自己的问题。我的重点是向具有使用强类型语言的背景的人解释它。

<强>任何

首先,您可以认为any是所有类型的超类型。就是这样! Any可用于引用任何实例。

TypeScript规范还定义了任何可分配的 TO 所有类型。这是按照定义,其基本原理可能是javascript互操作。来自规范:

  

“Any类型是所有类型的超类型,可分配给和   来自各种类型。“

任何作为通用参数

静态类型语言也具有“协方差”和“逆变”的概念。当泛型参数用作输出类型时,它可以替换基类型(协方差)。例如:'string的迭代器'可以分配给'对象的迭代器'。当泛型参数用作输入类型时,它可以替换派生类型(逆变)。

因为any可以从所有类型分配,所以对于参数化类型也是如此。因此Observable<Teacher>可以转换为Observable<any>

类型断言

TypeScript类型断言可用于更改实例的感知类型。由于TypeScript是结构类型语言,类型描述实例的结构,但实例本身并不知道类型(在断言中使用)。断言类型时,我们不应该使用具有除实例之外的其他成员的类型。例如,在res.json()的情况下,我们不希望类型具有方法成员,因为它是通过http get调用检索的数据。类型是类还是接口并不重要。