Json in TypeScript

TypeScript offers built-in support for JSON encoding and decoding, including to and from built-in and custom data types.

// We'll use these two interfaces to demonstrate encoding and
// decoding of custom types below.
interface Response1 {
    Page: number;
    Fruits: string[];
}

// Only public properties will be encoded/decoded in JSON.
interface Response2 {
    page: number;
    fruits: string[];
}

function main() {
    // First we'll look at encoding basic data types to
    // JSON strings. Here are some examples for atomic
    // values.
    console.log(JSON.stringify(true));
    console.log(JSON.stringify(1));
    console.log(JSON.stringify(2.34));
    console.log(JSON.stringify("gopher"));

    // And here are some for slices and maps, which encode
    // to JSON arrays and objects as you'd expect.
    const slcD = ["apple", "peach", "pear"];
    console.log(JSON.stringify(slcD));

    const mapD = { "apple": 5, "lettuce": 7 };
    console.log(JSON.stringify(mapD));

    // The JSON package can automatically encode your
    // custom data types. It will only include public
    // properties in the encoded output and will by default
    // use those names as the JSON keys.
    const res1D: Response1 = {
        Page: 1,
        Fruits: ["apple", "peach", "pear"]
    };
    console.log(JSON.stringify(res1D));

    // You can use interfaces to customize the encoded JSON
    // key names. Check the definition of `Response2` above
    // to see an example of such properties.
    const res2D: Response2 = {
        page: 1,
        fruits: ["apple", "peach", "pear"]
    };
    console.log(JSON.stringify(res2D));

    // Now let's look at decoding JSON data into TypeScript
    // values. Here's an example for a generic data
    // structure.
    const byt = '{"num":6.13,"strs":["a","b"]}';

    // We need to provide a variable where the JSON
    // package can put the decoded data. This
    // `Record<string, any>` will hold a map of strings
    // to arbitrary data types.
    let dat: Record<string, any>;

    // Here's the actual decoding, and a check for
    // associated errors.
    try {
        dat = JSON.parse(byt);
        console.log(dat);
    } catch (err) {
        console.error(err);
    }

    // In order to use the values in the decoded map,
    // we'll need to cast them to their appropriate type.
    // For example here we cast the value in `num` to
    // the expected `number` type.
    const num = dat["num"] as number;
    console.log(num);

    // Accessing nested data requires a series of
    // casts.
    const strs = dat["strs"] as any[];
    const str1 = strs[0] as string;
    console.log(str1);

    // We can also decode JSON into custom data types.
    // This has the advantages of adding additional
    // type-safety to our programs and eliminating the
    // need for type assertions when accessing the decoded
    // data.
    const str = '{"page": 1, "fruits": ["apple", "peach"]}';
    const res = JSON.parse(str) as Response2;
    console.log(res);
    console.log(res.fruits[0]);

    // In the examples above we always used strings as
    // intermediates between the data and JSON representation.
    // We can also stream JSON encodings directly to writers
    // like `process.stdout` or even HTTP response bodies.
    const d = { "apple": 5, "lettuce": 7 };
    process.stdout.write(JSON.stringify(d));
}

main();

To run this TypeScript program, you would typically compile it to JavaScript first and then run it with Node.js. Here’s what the output might look like:

true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"Page":1,"Fruits":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
{ num: 6.13, strs: [ 'a', 'b' ] }
6.13
a
{ page: 1, fruits: [ 'apple', 'peach' ] }
apple
{"apple":5,"lettuce":7}

We’ve covered the basics of JSON in TypeScript here, but for more details, you might want to check out the TypeScript documentation on working with JSON.