source

JSON 개체를 TypeScript 개체로 해석하는 방법

manycodes 2023. 3. 27. 21:22
반응형

JSON 개체를 TypeScript 개체로 해석하는 방법

수신한 JSON 오브젝트를 동일한 속성을 가진 TypeScript 클래스로 변환하려고 하는데 작동하지 않습니다.내가 뭘 잘못하고 있지?

종업원 클래스

export class Employee{
    firstname: string;
    lastname: string;
    birthdate: Date;
    maxWorkHours: number;
    department: string;
    permissions: string;
    typeOfEmployee: string;
    note: string;
    lastUpdate: Date;
}

종업원 문자열

{
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": <anynumber>,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
    //I will add note later
}

마이 어택

let e: Employee = new Employee();

Object.assign(e, {
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": 3,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
});

console.log(e);

타이프스크립트 놀이터 링크

클래스 대신 타입 스크립트 인터페이스를 사용하면 다음과 같이 작업이 단순해집니다.

export interface Employee {
    typeOfEmployee_id: number;
    department_id: number;
    permissions_id: number;
    maxWorkHours: number;
    employee_id: number;
    firstname: string;
    lastname: string;
    username: string;
    birthdate: Date;
    lastUpdate: Date;
}

let jsonObj = JSON.parse(employeeString); // string to "any" object first
let employee = jsonObj as Employee;

하지만, 만약 여러분이 수업을 원한다면, 단순한 캐스팅은 효과가 없을 것입니다.예를 들어 다음과 같습니다.

class Foo {
    name: string;
    public pump() { }
}

let jsonObj = JSON.parse('{ "name":"hello" }');
let fObj = jsonObj as Foo;
fObj.pump(); // crash, method is undefined!

클래스의 경우 JSON 문자열/개체를 받아들이는 생성자를 작성한 후 속성을 반복하여 다음과 같이 각 멤버를 수동으로 할당해야 합니다.

class Foo {
    name: string;

    constructor(jsonStr: string) {
        let jsonObj = JSON.parse(jsonStr);
        for (let prop in jsonObj) {
            this[prop] = jsonObj[prop];
        }
    }
}

let fObj = new Foo(theJsonString);

컴파일러가 반환된 오브젝트를 캐스팅할 수 있는 이유JSON.parse타이프 스크립트는 구조 서브타이핑에 기초하기 때문입니다.
당신은 정말 그런 예가 없어요.Employee(콘솔에 표시된 것과 같이) 동일한 속성을 가진 개체가 있습니다.

간단한 예:

class A {
    constructor(public str: string, public num: number) {}
}

function logA(a: A) {
    console.log(`A instance with str: "${ a.str }" and num: ${ a.num }`);
}

let a1 = { str: "string", num: 0, boo: true };
let a2 = new A("stirng", 0);
logA(a1); // no errors
logA(a2);

(운동장 코드)

에러는 없습니다.a1유형을 만족시키다A왜냐하면 그것은 모든 특성을 가지고 있고logA수신된 것이 의 인스턴스가 아니더라도 실행 시 오류 없이 함수를 호출할 수 있습니다.A같은 성질을 가진다면 말이죠.

클래스가 단순한 데이터 객체이고 메서드가 없는 경우 이 방법은 매우 효과적이지만 메서드를 도입하면 다음과 같은 문제가 발생하기 쉽습니다.

class A {
    constructor(public str: string, public num: number) { }

    multiplyBy(x: number): number {
        return this.num * x;
    }
}

// this won't compile:
let a1 = { str: "string", num: 0, boo: true } as A; // Error: Type '{ str: string; num: number; boo: boolean; }' cannot be converted to type 'A'

// but this will:
let a2 = { str: "string", num: 0 } as A;

// and then you get a runtime error:
a2.multiplyBy(4); // Error: Uncaught TypeError: a2.multiplyBy is not a function

(운동장 코드)


편집

이 기능은 정상적으로 동작합니다.

const employeeString = '{"department":"<anystring>","typeOfEmployee":"<anystring>","firstname":"<anystring>","lastname":"<anystring>","birthdate":"<anydate>","maxWorkHours":0,"username":"<anystring>","permissions":"<anystring>","lastUpdate":"<anydate>"}';
let employee1 = JSON.parse(employeeString);
console.log(employee1);

(운동장 코드)

를 사용하려는 경우JSON.parse오브젝트가 문자열이 아닌 경우:

let e = {
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": 3,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
}
let employee2 = JSON.parse(e);

그러면 문자열이 아니라 오브젝트이기 때문에 에러가 발생합니다.이미 이 형태로 가지고 있는 경우에는 사용할 필요가 없습니다.JSON.parse.

그런데 제가 쓴 것처럼 이렇게 하면 수업의 인스턴스가 아니라 수업 멤버와 같은 속성을 가진 오브젝트일 뿐입니다.

인스턴스가 필요한 경우:

let e = new Employee();
Object.assign(e, {
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": 3,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
});
let employee = <Employee>JSON.parse(employeeString);

주의:강력한 타이핑은 javascript를 지원하지 않기 때문에 컴파일 시간에만 사용할 수 있습니다.

JSON 데이터에 클래스에 없는 속성이 있을 수 있습니다.매핑의 경우 간단한 사용자 지정 매핑을 수행할 수 있습니다.

export class Employe{ ////
    static parse(json: string) {
           var data = JSON.parse(json);
            return new Employe(data.typeOfEmployee_id, data.firstName.. and others);
       }
}

또한 컨스트럭터를 지정합니다.Employee학급.

나는 수업시간표라고 불리는 아주 작은 도서관을 이용하는 것을 좋아한다.

nested-parames, date-parames에 스트링을 매핑하고 다양한 json-parames-names를 처리할 수 있습니다.

한 번 볼만 하군

import { Type, plainToClass, Expose } from "class-transformer";
import 'reflect-metadata';

export class Employee{
    @Expose({ name: "uid" })
    id: number;

    firstname: string;
    lastname: string;
    birthdate: Date;
    maxWorkHours: number;
    department: string;

    @Type(() => Permission)
    permissions: Permission[] = [];
    typeOfEmployee: string;
    note: string;

    @Type(() => Date)
    lastUpdate: Date;
}

export class Permission {
  type : string;
}

let json:string = {
    "uid": 123,
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": 1,
    "username": "<anystring>",
    "permissions": [
      {'type' : 'read'},
      {'type' : 'write'}
    ],
    "lastUpdate": "2020-05-08"
}

console.log(plainToClass(Employee, json));

```

우선, 서비스로부터 취득하는 모든 어트리뷰트의 이름이 클래스내에서 같게 되어 있는 것을 확인할 필요가 있습니다.그런 다음 개체를 구문 분석하고 새 변수에 다음과 같이 할당할 수 있습니다.

const parsedJSON = JSON.parse(serverResponse);
const employeeObj: Employee = parsedJSON as Employee;

먹어봐!

클래스에서 생성자 프로시저를 사용해 보십시오.

Object.assign(Object.assign)

열쇠입니다.

이 샘플을 봐주세요.

class Employee{
    firstname: string;
    lastname: string;
    birthdate: Date;
    maxWorkHours: number;
    department: string;
    permissions: string;
    typeOfEmployee: string;
    note: string;
    lastUpdate: Date;

    constructor(original: Object) { 
        Object.assign(this, original);
    }
}

let e = new Employee({
    "department": "<anystring>",
    "typeOfEmployee": "<anystring>",
    "firstname": "<anystring>",
    "lastname": "<anystring>",
    "birthdate": "<anydate>",
    "maxWorkHours": 3,
    "username": "<anystring>",
    "permissions": "<anystring>",
    "lastUpdate": "<anydate>"
});
console.log(e);

다음과 같이 json을 캐스팅할 수 있습니다.

수업 내용:

export class Employee{
    firstname: string= '';
}

및 json:

let jsonObj = {
    "firstname": "Hesham"
};

다음과 같이 캐스팅할 수 있습니다.

let e: Employee = jsonObj as Employee;

리리 of의 console.log(e); 말합니다

{ 이름: 'Hesham' }

클래스의 새 개체를 만든 다음 JSON 개체의 매개 변수에서 해당 매개 변수를 동적으로 할당할 수 있습니다.

const employeeData = JSON.parse(employeeString);
let emp:Employee=new Employee();
const keys=Object.keys(employeeData);
keys.forEach(key=>{
    emp[key]=employeeData[key];
});
console.log(emp);

현재 emp는 EmployeeString의 Json 객체(employeeData)의 모든 필드를 포함하는 Employee 객체입니다.

구문 "as"를 사용하여 이 작업을 수행할 수 있습니까?

async getProfile(): Promise<Contact> {
      const url: string = this.baseApi;
    
      const response = await this.http.get(url).toPromise()
      return JSON.parse(response.json()) as Contact;
    }
if it is coming from server as object you can do 

this.service 를 참조해 주세요.서브스크라이브(data:any) 모든 유형의 데이터를 유지하면 문제가 해결됩니다.

언급URL : https://stackoverflow.com/questions/40421100/how-to-parse-a-json-object-to-a-typescript-object

반응형