typescript 打字稿:在订阅或地图中投射类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39327500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Typescript: Cast type in subscribe or in map
提问by Salman Lashkarara
I receive a json from the backend which contains an array of client
object:
Here is the client class:
我从后端收到一个包含client
对象数组的 json :这是客户端类:
export class Client {
private id:number;
private firstname: String;
private lastname: String;
private phone:String;
private address:String;
private country:String;
private Security_No:String;
}
I am looking for easiest way to cast the received json
to a Clients[]
.
currently i store the json in an attribute, and later i go throw it and extract data fram it. but it seems that, there should be an easier way?
我正在寻找最简单的方法将接收json
到的Clients[]
. 目前我将 json 存储在一个属性中,然后我去扔它并从中提取数据。但似乎,应该有更简单的方法?
populateClientData() {
this._httpClientService.getAllClients().subscribe((res)=>this.data=res.json()))
}
回答by Nitzan Tomer
You can not cast json data (that is, js objects) into classes.
Well, you can, but then you don't really have instances of the class but objects that satisfy the class interface.
您不能将 json 数据(即 js 对象)转换为类。
嗯,你可以,但是你并没有真正拥有类的实例,而是拥有满足类接口的对象。
Simple example:
简单的例子:
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
let a = {
x: 5,
y: 5
} as Point;
console.log(a); // Object {x: 5, y: 5}
let b = new Point(5, 5);
console.log(b); // Point {x: 5, y: 5}
The compiler won't complain about a
not being an instance of Point
because it satisfies the Point
interface, so these are valid:
编译器不会因为它满足接口而抱怨a
不是实例,所以这些是有效的:Point
Point
function log(point: Point) {
console.log(`(${ point.x }, ${ point.y })`);
}
log(a); // fine
log(b); // fine
(操场上的代码)
It works this way because:
它以这种方式工作,因为:
One of TypeScript's core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.
TypeScript 的核心原则之一是类型检查侧重于值的形状。这有时被称为“鸭子类型”或“结构子类型”。在 TypeScript 中,接口扮演着命名这些类型的角色,并且是在代码中定义契约以及与项目外部代码的契约的强大方式。
As for you specific problem, you can use your class as an interface or just make it into an interface:
至于您的具体问题,您可以将您的类用作接口或将其变成接口:
interface Client {
id:number;
firstname: String;
lastname: String;
phone:String;
address:String;
country:String;
Security_No:String;
}
And then (in both cases):
然后(在这两种情况下):
this._httpClientService.getAllClients().subscribe((res) => {
this.data = res.json() as Client[]
}));
But if you'll use your class (and not the interface) then the properties must be public and not private.
但是如果你要使用你的类(而不是接口),那么属性必须是公共的而不是私有的。
If you wish to use your class as a class and not interface then casting won't do, you'll need to:
如果您希望将类用作类而不是接口,则无法进行转换,您需要:
this._httpClientService.getAllClients().subscribe((res) => {
this.data = res.json().map(item => new Client(data));
}));
And you'll need to have a constructor for Client
which accepts the interface and assigns the values to its members.
并且您需要有一个构造函数,Client
它接受接口并将值分配给其成员。
回答by John Baird
In my app, I have a user object that has many fields and a number of arrays to store data so it's a complex object. In the map operator, I can cast the response.json()
to that value like this:
在我的应用程序中,我有一个用户对象,它有许多字段和许多数组来存储数据,因此它是一个复杂的对象。在 map 运算符中,我可以将response.json()
转换为该值,如下所示:
return this.http.get(this.constants.userUrl + userId, { headers: headers })
.map((response: Response) => <User>response.json())
.catch(this.handleError);
}
The subscribe is handled the same way:
订阅的处理方式相同: