chris01
chris01

Reputation: 12331

Typescript: Object to class

Lets say I have a class C and an Instance of Object O (from JSON).

class C {
  str:string;
  num:number;
}

var o = JSON.parse ("{\"num\":123, \"str\":\"abc\"}");

Is there a way I can assign/initialize an instance of C with o and it checks for undefined values as well as for the type WITHOUT doing it by myself in a copy-constructor/function?

I'd like to get an error or exception if a value is missing/undefined or the type does not match.

Thanks!

Upvotes: 13

Views: 22084

Answers (5)

zupa
zupa

Reputation: 13442

I landed here wanting to create a class instance from an object literal. Object.assign() works but it isn't type safe. Of course, if you have JSON source that's expected but I just wanted to instantiate a class with a known state.

From the TypeScript docs, a class also acts as a type. Thus, the following will work:

class C {
    str: string;
    num: number;

    constructor(source: Partial<C>) {
        Object.assign(this, source);
    }
}

// Ok - all properties
const c1 = new C({
    num: 123,
    str: "abc"
});

// Ok - only some of the properties
const c1 = new C({
    num: 123,
});

// Error: unknown property `unexpectedPropertyName`
const c2 = new C({
    num: 123,
    unexpectedPropertyName: "abc"
});

Upvotes: 9

Patrick
Patrick

Reputation: 236

You can use Object.assign:

class C {
    str:string;
    num:number;
}
var o = JSON.parse("{\"num\":123, \"str\":\"abc\"}");
const instance:C = Object.assign(new C(), o);

Upvotes: 22

RainingChain
RainingChain

Reputation: 7746

What you are asking for is a JSON schema validator. The validation must be ran in runtime. Check https://github.com/epoberezkin/ajv for a complete JSON schema validator or https://www.npmjs.com/package/js-schema for a simpler one.

Upvotes: 2

adz5A
adz5A

Reputation: 2032

Typescript is a type system that runs at compile time, what you are asking is therefore impossible.

You could have a look at type guards and maybe use them to provide type inference inside a conditional block of some kind of parse function.

Upvotes: 0

Kokodoko
Kokodoko

Reputation: 28128

Here is an example of creating objects directly, which will give you live error checking. The problem with JSON.parse it that the compiler will not check at compile time what it returns. If you work with unknown live data you will have to write some error check manually.

interface Obj {
  str: string
  num: number
}

class C {
  constructor(o:Obj) { 

  }
}

var o = {test:43, str:"abc"}
var p = {num:43, str:"abc"}

var instanceOne = new C(o) // not allowed
var instanceTwo = new C(p) // allowed

Upvotes: 3

Related Questions