在尝试找出将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
?答案 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调用检索的数据。类型是类还是接口并不重要。