来自JSON的Typescript对象

来自JSON的Typescript对象,json,angular,typescript,Json,Angular,Typescript,我正在使用TypeScript构建一个应用程序,并且正在进行API调用以检索对象。例如,我有一个TypeScript用户对象,如下所示: export class User { id : number; name : string; email : string; } 我的API返回 { "id" : 3, "name" : "Jonn", "email" : "john@example.com" } 我想将JSON转换为用户。我在另一篇文章中

我正在使用TypeScript构建一个应用程序,并且正在进行API调用以检索对象。例如,我有一个TypeScript用户对象,如下所示:

export class User {
    id : number;
    name : string;
    email : string;
}
我的API返回

{
    "id" : 3,
    "name" : "Jonn",
    "email" : "john@example.com"
}
我想将JSON转换为用户。我在另一篇文章中读到我可以做到这一点:

let user : User = <User> myJson;
发生这种情况: user.name返回John,但user.getUppercaseName返回undefined


发生什么事了?如何解决这个问题

将类视为接口,因为这样做的效果完全相同:

export interface User {
    id : number;
    name : string;
    email : string;
}
编译器不会抱怨您以这种方式使用类的原因:

TypeScript的核心原则之一是类型检查的重点是 值所具有的形状。这有时被称为“鸭子打字”或 “结构子类型”

或者举个例子:

class User {
    id: number;
    name: string;
    email: string;

    constructor(id: number, name: string, email: string) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}

function logUser(user: User) {
    console.log(`user id: ${ user.id }, name: ${ user.name }, email: ${ user.email }`);
}

logUser({
    id: 1,
    name: "user 1",
    email: "mailaddress"
});

logUser(new User(2, "user 2", "anotheraddress"));
在对logUser的两个调用中,我传递满足User类接口的对象

如果希望拥有该类的实例,而不是满足该类的对象,则应执行以下操作:

new User(myJson.id, myJson.name, myJson.email);
并且有一个类似于我的示例中的构造函数,或者:

interface IUser {
    id: number;
    name: string;
    email: string;
}

class User implements IUser {
    id: number;
    name: string;
    email: string;

    constructor(data: IUser) {
        this.id = data.id;
        this.name = data.name;
        this.email = data.email;
    }
}

...
new User(myJson);

您所做的是将类视为接口,因为这将完全相同:

export interface User {
    id : number;
    name : string;
    email : string;
}
编译器不会抱怨您以这种方式使用类的原因:

TypeScript的核心原则之一是类型检查的重点是 值所具有的形状。这有时被称为“鸭子打字”或 “结构子类型”

或者举个例子:

class User {
    id: number;
    name: string;
    email: string;

    constructor(id: number, name: string, email: string) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}

function logUser(user: User) {
    console.log(`user id: ${ user.id }, name: ${ user.name }, email: ${ user.email }`);
}

logUser({
    id: 1,
    name: "user 1",
    email: "mailaddress"
});

logUser(new User(2, "user 2", "anotheraddress"));
在对logUser的两个调用中,我传递满足User类接口的对象

如果希望拥有该类的实例,而不是满足该类的对象,则应执行以下操作:

new User(myJson.id, myJson.name, myJson.email);
并且有一个类似于我的示例中的构造函数,或者:

interface IUser {
    id: number;
    name: string;
    email: string;
}

class User implements IUser {
    id: number;
    name: string;
    email: string;

    constructor(data: IUser) {
        this.id = data.id;
        this.name = data.name;
        this.email = data.email;
    }
}

...
new User(myJson);

Nitzan几乎解释了这背后的理论,因此我将提供一种替代方法:

interface UserInfo {
   id: number;
   name: string;
   email: string;
}

class User {
   userInfo: UserInfo;
   constructor(userInfo: UserInfo) {
       this.userInfo = userInfo;
   }
   getUpperCaseName(): string {
       return this.userInfo.name.toLocaleUpperCase();
   }
}

const json = {
   id: 3,
   name: "Jonn",
   email: "john@example.com"
}

let user: User = new User(json);

Nitzan几乎解释了这背后的理论,因此我将提供一种替代方法:

interface UserInfo {
   id: number;
   name: string;
   email: string;
}

class User {
   userInfo: UserInfo;
   constructor(userInfo: UserInfo) {
       this.userInfo = userInfo;
   }
   getUpperCaseName(): string {
       return this.userInfo.name.toLocaleUpperCase();
   }
}

const json = {
   id: 3,
   name: "Jonn",
   email: "john@example.com"
}

let user: User = new User(json);

当您的用户具有50个或更多属性时出现问题

在用户对象中添加构造函数,以便它扩展json对象

export class User {
    constructor( jsonUser: any )
    {
      $.extend(this, jsonUser);
    }
    id : number;
    name : string;
    email : string;
    getUpperCaseName() {...}
}
在ajax回调中,从json对象创建用户对象:

let receivedUser = new User( jsonUser );
let userName = receivedUser.getUpperCaseName();

我在其中详细介绍了解决方案。

当您的用户拥有50个或更多属性时,会出现问题

在用户对象中添加构造函数,以便它扩展json对象

export class User {
    constructor( jsonUser: any )
    {
      $.extend(this, jsonUser);
    }
    id : number;
    name : string;
    email : string;
    getUpperCaseName() {...}
}
在ajax回调中,从json对象创建用户对象:

let receivedUser = new User( jsonUser );
let userName = receivedUser.getUpperCaseName();

我详细介绍了解决方案。

我认为问题在于如何将json数据转换为特定的类实例。假设有一个用户的构造函数,类似的东西应该可以工作,但是当我在ngIf中使用结果时会给我错误。返回这个。\u http.getthis.urll.mapres:Response=>res.json.mapobj:any=>{返回新的Userobj.number,obj.name,obj.email;}@rook不需要使用map两次。。应该可以这样做:this.\u http.getthis.urll.mapres:Response=>{let json=res.json;返回新的Userjson.id、json.name、json.email;}。您会遇到什么错误?是的,它较短,但错误相同:找不到类型为“object”的不同支持对象“[object object]”。NgFor只支持绑定到数组之类的Iterables。@rook我建议您在发布代码的同时发布一个带有错误的新问题。评论中的代码/问题很难理解,加上一个新问题,除了我之外,你会有更多的人来帮助你。另外,这与这个问题或我的答案无关,我认为问题在于如何将json数据转换为特定的类实例。假设有一个用户的构造函数,类似的东西应该可以工作,但是当我在ngIf中使用结果时会给我错误。返回这个。\u http.getthis.urll.mapres:Response=>res.json.mapobj:any=>{返回新的Userobj.number,obj.name,obj.email;}@rook不需要使用map两次。。应该可以这样做:this.\u http.getthis.urll.mapres:Response=>{let json=res.json;返回新的Userjson.id、json.name、json.email;}。您会遇到什么错误?是的,它较短,但错误相同:找不到类型为“object”的不同支持对象“[object object]”。NgFor只支持绑定到数组之类的Iterables。@rook我建议您在发布代码的同时发布一个带有错误的新问题。评论中的代码/问题很难理解,加上一个新问题,除了我之外,你会有更多的人来帮助你。而且,这与这个问题或我的答案无关。