我从远程REST服务器读取了一个JSON对象。这个JSON对象具有typescript类的所有属性(根据设计)。我如何转换收到的JSON对象的类型var?

我不想填充一个typescript变量(即有一个构造函数,以这个JSON对象)。它很大,在子对象和属性之间复制所有内容将花费大量时间。

更新:你可以将它转换为typescript接口!


当前回答

将对象原样传递给类构造函数;没有约定或检查

interface iPerson {
   name: string;
   age: number;
}

class Person {
   constructor(private person: iPerson) { }

   toString(): string {
      return this.person.name + ' is ' + this.person.age;
   }  
}


// runs this as // 
const object1 = { name: 'Watson1', age: 64 };
const object2 = { name: 'Watson2' };            // age is missing

const person1 = new Person(object1);
const person2 = new Person(object2 as iPerson); // now matches constructor

console.log(person1.toString())  // Watson1 is 64
console.log(person2.toString())  // Watson2 is undefined

其他回答

你不能简单地将Ajax请求的原始JavaScript结果转换为典型的JavaScript/TypeScript类实例。有许多技术可以做到这一点,通常涉及到复制数据。除非创建类的实例,否则它不会有任何方法或属性。它仍然是一个简单的JavaScript对象。

而如果你只处理数据,你可以只做一个转换到一个接口(因为它是一个纯粹的编译时结构),这将需要你使用一个TypeScript类,它使用数据实例并对该数据执行操作。

一些复制数据的例子:

将AJAX JSON对象复制到现有对象 在JavaScript中将JSON字符串解析为特定对象原型

本质上,你只需要:

var d = new MyRichObject();
d.copyInto(jsonResult);

Java爱好者

创建POJO类

export default class TransactionDTO{
    constructor() {
    }
}

按类创建空对象

let dto = new TransactionDto()   // ts object
let json = {name:"Kamal",age:40} // js object

let transaction: TransactionDto = Object.assign(dto,JSON.parse(JSON.stringify(json)));//conversion

在后期TS,你可以这样做:

const isMyInterface = (val: any): val is MyInterface => {
  if (!val) { return false; }
  if (!val.myProp) { return false; }
  return true;
};

而用户是这样的:

if (isMyInterface(data)) {
 // now data will be type of MyInterface
}

就我个人而言,typescript不允许指定端点定义是令人震惊的 接收到的对象的类型。看来情况确实如此, 我会做我对其他语言做过的事情,那就是我将JSON对象从类定义中分离出来, 并让类定义使用JSON对象作为其唯一的数据成员。

我不喜欢样板代码,所以对我来说,这通常是在保留类型的同时用最少的代码得到想要的结果。

考虑以下JSON对象结构定义——这些将是您在端点处接收到的内容,它们只是结构定义,没有方法。

interface IAddress {
    street: string;
    city: string;
    state: string;
    zip: string;
}

interface IPerson {
    name: string;
    address: IAddress;
}

如果我们用面向对象的术语来考虑上面的内容,那么上面的接口就不是类,因为它们只定义了一个数据结构。 面向对象术语中的类定义了数据和对其进行操作的代码。

因此,我们现在定义了一个类,它指定数据和对其进行操作的代码……

class Person {
    person: IPerson;

    constructor(person: IPerson) {
        this.person = person;
    }

    // accessors
    getName(): string {
        return person.name;
    }

    getAddress(): IAddress {
        return person.address;
    }

    // You could write a generic getter for any value in person, 
    // no matter how deep, by accepting a variable number of string params

    // methods
    distanceFrom(address: IAddress): float {
        // Calculate distance from the passed address to this persons IAddress
        return 0.0;
    }
}

现在我们可以简单地传入任何符合IPerson结构的对象,然后继续我们的方法…

   Person person = new Person({
            name: "persons name",
            address: {
                street: "A street address",
                city: "a city",
                state: "a state",
                zip: "A zipcode"
            }
        });

以同样的方式,我们现在可以处理从您的端点接收到的对象,内容如下所示:

Person person = new Person(req.body);    // As in an object received via a POST call

person.distanceFrom({ street: "Some street address", etc.});

这样的性能更高,并且使用了复制数据时一半的内存,同时显著减少了必须为每种实体类型编写的样板代码的数量。 它仅仅依赖于TypeScript提供的类型安全性。

我也遇到过类似的需求。 我想要一些能够让我轻松地从/转换到JSON的东西 这来自于对特定类定义的REST api调用。 我已经找到的解决方案是不够的,或者意味着重写我的 类的代码和添加注释或类似内容。

我想在Java中使用类似GSON的东西来序列化/反序列化类到JSON对象。

结合后来的需要,转换器也可以在JS中运行,我结束了编写自己的包。

它有一些开销。但启动后,添加和编辑非常方便。

初始化模块:

转换模式——允许在字段之间进行映射和确定 如何进行转换 类映射数组 转换函数映射-用于特殊转换。

然后在你的代码中,你像这样使用初始化的模块:

const convertedNewClassesArray : MyClass[] = this.converter.convert<MyClass>(jsonObjArray, 'MyClass');

const convertedNewClass : MyClass = this.converter.convertOneObject<MyClass>(jsonObj, 'MyClass');

或者,转换为JSON:

const jsonObject = this.converter.convertToJson(myClassInstance);

使用这个链接到npm包,以及如何使用模块:json-class-converter的详细说明

还包装了 Angular的用法: angular-json-class-converter