Reputation: 12331
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
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
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
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
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
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