Given the Typescript code snippet:
class Excel {
Password: string;
Sheet: number;
}
class Csv {
Separator: string;
Encoding: string;
}
type FileType = Excel | Csv
let input = '{"Separator": ",", "Encoding": "UTF-8"}';
let output = Object.setPrototypeOf(JSON.parse(input), FileType.prototype) // error!
In TypeScript/Javascript, to deserialize from JSON, one can use Object.setPrototypeOf()
, the second parameter of which requires a "prototype". With classes, e.g. Excel
, one can just do Excel.prototype
. But with Discriminated Union as above, I encountered an error:
error TS2693: 'FileType' only refers to a type, but is being used as a value here.
Question:
- Is there any way to deserialize a Discriminated Union in TypeScript?
- If not, is there any other elegant way to realize the scenario above (given two classes:
Excel
/Csv
and JSON string serializing either of them; get back the correct instantiated object), regardless of whatever tricks, classes, class inheritance, interface, discriminated union or not...?
Environment
- Typescript v2.9.2
- Visual Studio Code v1.25.1
My try
let json = JSON.parse(input);
let output: FileType | null = null;
if (json["Separator"]) {
console.log("It's csv");
output = Object.setPrototypeOf(json, Csv.prototype)
} else if (json["Password"]) {
console.log("It's excel");
output = Object.setPrototypeOf(json, Excel.prototype)
} else {
console.log("Error");
}
It's easy to recognize that this approach is cumbersome (if else
alot), especially when adding new classes. Additionally, developers have to choose a unique field for checking in each class...