TypeScript protocol for a JSON response object (from node.js backend for example):
interface Circle {
type: "circle";
radius: number;
}
interface Square {
type: "square";
size: number;
}
type Figure = Circle | Square;
interface Response {
figure?: Figure;
}
Possible response examples:
{
"figure": {
"type": "square",
"size": 1.24
}
}
{
"figure": {
"type": "circle",
"radius": 3.25
}
}
{ }
C# response deserialization:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Guess
{
public sealed class Square
{
public String Type { get; set; }
public Single Size { get; set; }
public static readonly String ExpectedType = "square";
}
public sealed class Circle
{
public String Type { get; set; }
public Single Radius { get; set; }
public static readonly String ExpectedType = "circle";
}
public sealed class Response
{
[JsonProperty("figure")]
public JToken FigureRaw { get; set; }
[JsonIgnore]
public Object Figure
{
get
{
if (this.TryGetFigureType(out var type))
{
return this.FigureRaw.ToObject(type);
}
else
{
return null;
}
}
}
private Boolean TryGetFigureType(out Type value)
{
if (this.FigureRaw == null)
{
value = null;
return false;
}
var type = this.FigureRaw.Value<String>("type");
if (type == Square.ExpectedType)
{
value = typeof(Square);
return true;
}
else if (type == Circle.ExpectedType)
{
value = typeof(Circle);
return true;
}
throw new NotSupportedException($"Not supported figure type: {type}");
}
}
class Program
{
static void Main(String[] args)
{
var responses = new []
{
JsonConvert.DeserializeObject<Response>(@"{ ""figure"": { ""type"": ""square"", ""size"": 1.24 } }"),
JsonConvert.DeserializeObject<Response>(@"{ ""figure"": { ""type"": ""circle"", ""radius"": 3.25 } }"),
JsonConvert.DeserializeObject<Response>(@"{ }"),
};
foreach (var response in responses)
{
var figure = response.Figure;
switch (figure)
{
case null:
Console.WriteLine("Figure has not been set");
break;
case Square square:
Console.WriteLine($"Square size: {square.Size}");
break;
case Circle circle:
Console.WriteLine($"Circle radius: {circle.Radius}");
break;
default:
throw new NotSupportedException($"Not supported figure type: {figure.GetType()}");
}
}
}
}
}