Safely Handling Dynamic Data with TypeScript

Rate this content
Bookmark

TypeScript makes JavaScript safer adding static type definitions. Static definitions are wonderful; they prevent developers from making trivial mistakes ensuring every assignment and invocation is done correctly. A variable typed as a string cannot be assigned a number, and a function expecting three arguments cannot be called with only two. These definitions only exist at build time though; the code that is eventually executed is just JavaScript. But what about the response from an API request? In this talk Ethan Arrowood, Software Engineer 2 @ Microsoft, he will cover various solutions for safely typing dynamic data in TypeScript applications. This talk features popular technologies such as Fastify, JSON Schema, Node.js, and more!

This talk has been presented at Node Congress 2021, check out the latest edition of this JavaScript Conference.

FAQ

Yes, JSON Schema is primarily intended for validating data at runtime to ensure it matches the defined schema. This is crucial in dynamic environments where data integrity is vital, such as in API data exchange and configuration validation processes.

TypeBox is a library that allows defining JSON schemas using a fluent API and deriving static types from those schemas for use in TypeScript code. This helps in maintaining consistency between the data structure and its type definition, enhancing type safety in TypeScript applications.

While TypeScript interfaces provide compile-time type checking, JSON Schema offers runtime validation, which is essential for data that comes from external sources. JSON Schema also allows for more detailed data validation rules than TypeScript interfaces, such as pattern matching and value constraints.

TypeBox can theoretically be used to define JSON Schemas that are compatible with OpenAPI specifications. However, additional steps might be required to convert these schemas into a format that fully complies with OpenAPI standards, typically involving further tooling or manual adjustments.

Fastify utilizes JSON Schema to validate incoming data against predefined schemas before reaching the route handler. This ensures that the data structure adheres to the expected format, enhancing security and reliability. Type safety is further enforced by mapping these schemas to TypeScript types using libraries like TypeBox.

JSON Schema is a specification that allows developers to define the structure of a JSON object using JSON itself. It's used in TypeScript to ensure that JSON objects match a predefined schema, aiding in type safety and validation, particularly in API interactions and data handling scenarios.

Ethan Arrowood
Ethan Arrowood
29 min
24 Jun, 2021

Comments

Sign in or register to post your comment.
Video Summary and Transcription
This Talk discusses the safe handling of dynamic data with TypeScript using JSON Schema and TypeBox. Fastify, a web framework, allows developers to validate incoming data using JSON schema, providing type safety and error handling. TypeBox is a powerful library that allows developers to define JSON schemas and derive static types in TypeScript. The combination of JSON schema, TypeBox, and Fastify provides powerful tools for type safety and validation of dynamic data.

1. Introduction to Handling Dynamic Data

Short description:

Hello, everybody. Today I'm going to be talking to you all about safely handling dynamic data with TypeScript. We use data in various ways as software developers, such as API routes, forms, authentication payloads, and communication between large systems. Let's look at an example of a JSON object representing a person. JSON is a verbose way of representing data and is widely used in APIs. Now, let's explore a Fastify route and the challenges of handling unknown request bodies.

Hello, everybody. My name is Ethan Erewood. I'm a software engineer for Microsoft and today I'm going to be talking to you all about safely handling dynamic data with TypeScript.

So, handling data. What is data? As software developers, we use a lot of it and in a lot of different ways. Some good examples, at least of how I use it is within API routes, when building a back end service, dealing with forms in the front end, and also authentication payloads and all of the surrounding things that go with authentication in an entire full stack application. And this is just a short list. You can only imagine how long this can get when you start dealing with databases or data science and just general, any sort of communication between large systems.

So, let's take a peek at an example of a record of data. In this case, I'm using a JSON object. We got a bunch of keys here. ID, name, employed, company, age, and projects. We're representing a person. Maybe this is an employee directory or maybe it's a user directory for a site such as LinkedIn where we have a user, we want to get their name, we want to know are they employed or not, which is a Boolean value. We want to know what company they work for. We want to know how old they are. And we also might want to list their projects. And as many folks know, JSON is a very verbose way of representing data. There are it has a lot of great primitives that are all based in JavaScript, and it can be quite extensive. In fact, entire APIs are powered by just JSON projects alone through the open schema format.

Talking about backend APIs, let's take a look at a Fastify route. In this case, we're defining a post route. The path is add user, and the request handler here has two arguments, request and response, and we're destructuring the body from that request object. Does anyone know what type body might be? Is it a record, an object, is it any type? Trick question. It's unknown. The body property of that request object, taking a peek again at the code, the Fastify route has no idea what it is because in context of Fastify as a framework, we're not sure what the developer intends to be coming in through their request. And there's no way for Fastify to know that when you're right when the code is being written or even compiled. Well, maybe not when it's compiled. We'll get to that later. So let's take another look here.

2. Handling Unknown Request Bodies with JSON Schema

Short description:

Looking at the previous JSON object or take a slice of look at the ID and the name, there are string keys and string values. TypeScript will throw an error. Object is of type unknown. So there's some patterns we can use. You can use basic typecasting where we can say body.name as string. But in that case, there is no verification. That's where I want to introduce JSON Schema. JSON Schema is a super powerful API, lets you define a JSON object with more JSON. JSON Schema uses a standard or a specification to allow a developer to define the shape of a JSON object, given things such as the type, listing the properties, saying what properties are required or not, listing if there are additional properties or not, and even being able to define more complex types. JSON schema, and this only scratches the surface of JSON schema. You can use regular expressions, you can use references, you can use logical operations like all of or any and or some, and it's just so powerful when you leverage JSON schema to define your JSON objects.

Looking at the previous JSON object or take a slice of look at the ID and the name, there are string keys and string values. And then looking at the post route again, we know that body is unknown that we're destructuring from the request object. So what would be body.name? In this case, imagine that the JSON object is being sent to this route as the body in the post request. So what would name be? Probably a string, right? Well, a trick question again. TypeScript will throw an error. Object is of type unknown. Why is that? Well, it's because the body property is coming from that request object. Because it's unknown. No other types can be derived from it in safely, in TypeScript. TypeScript goes, no, no, no, stop here. I don't want you to keep going and using properties on this object because as the TypeScript compiler, I don't know what it is. And I can't provide you the type safety that you're looking for. So even though, as a user, we might think, ah, the name property, it's always going to be a string, there's no if-ans or buts about it. In this case, TypeScript is like, well, you didn't tell me that. I have no way of assuring that. So there's some patterns we can use. You can use basic typecasting where we can say body.name as string, and we will tell TypeScript it's a string. But in that case, there is no verification. There's no way of saying that assuring that that name property is actually a string because TypeScript is a compile time only type safety. During runtime, it's all just JavaScript. There is no type safety at the runtime. So what are some other solutions? That's where I want to introduce JSON Schema. JSON Schema is a super powerful API, lets you define a JSON object with more JSON. Isn't that just wonderful? Kidding aside, JSON Schema is actually incredibly verbose, even more verbose than the JSON object it's probably defining. JSON Schema uses a standard or a specification to allow a developer to define the shape of a JSON object, given things such as the type, listing the properties, saying what properties are required or not, listing if there are additional properties or not, and even being able to define more complex types. As you can see in the code sample, the projects property is of type array and then we get to go even further and say the items of that array are of type string. JSON schema, and this only scratches the surface of JSON schema. You can use regular expressions, you can use references, you can use logical operations like all of or any and or some, and it's just so powerful when you leverage JSON schema to define your JSON objects. So all that said, though, JSON schema, I think it's even in their spec, is intended for validation. The validation in a sense of here's a schema and here's a JSON object.

QnA

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React's Most Useful Types
React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
Top Content
Watch video: React's Most Useful Types
Today's Talk focuses on React's best types and JSX. It covers the types of JSX and React components, including React.fc and React.reactnode. The discussion also explores JSX intrinsic elements and react.component props, highlighting their differences and use cases. The Talk concludes with insights on using React.componentType and passing components, as well as utilizing the react.element ref type for external libraries like React-Select.
TypeScript and React: Secrets of a Happy Marriage
React Advanced 2022React Advanced 2022
21 min
TypeScript and React: Secrets of a Happy Marriage
Top Content
React and TypeScript have a strong relationship, with TypeScript offering benefits like better type checking and contract enforcement. Failing early and failing hard is important in software development to catch errors and debug effectively. TypeScript provides early detection of errors and ensures data accuracy in components and hooks. It offers superior type safety but can become complex as the codebase grows. Using union types in props can resolve errors and address dependencies. Dynamic communication and type contracts can be achieved through generics. Understanding React's built-in types and hooks like useState and useRef is crucial for leveraging their functionality.
Making Magic: Building a TypeScript-First Framework
TypeScript Congress 2023TypeScript Congress 2023
31 min
Making Magic: Building a TypeScript-First Framework
Top Content
Daniel Rowe discusses building a TypeScript-first framework at TypeScript Congress and shares his involvement in various projects. Nuxt is a progressive framework built on Vue.js, aiming to reduce friction and distraction for developers. It leverages TypeScript for inference and aims to be the source of truth for projects. Nuxt provides type safety and extensibility through integration with TypeScript. Migrating to TypeScript offers long-term maintenance benefits and can uncover hidden bugs. Nuxt focuses on improving existing tools and finds inspiration in frameworks like TRPC.
Stop Writing Your Routes
Vue.js London 2023Vue.js London 2023
30 min
Stop Writing Your Routes
Designing APIs is a challenge, and it's important to consider the language used and different versions of the API. API ergonomics focus on ease of use and trade-offs. Routing is a misunderstood aspect of API design, and file-based routing can simplify it. Unplugging View Router provides typed routes and eliminates the need to pass routes when creating the router. Data loading and handling can be improved with data loaders and predictable routes. Handling protected routes and index and ID files are also discussed.
Get rid of your API schemas with tRPC
React Day Berlin 2022React Day Berlin 2022
29 min
Get rid of your API schemas with tRPC
Today's Talk introduces TRPC, a library that eliminates the need for code generation and provides type safety and better collaboration between front-end and back-end. TRPC is demonstrated in a Next JS application integrated with Prisma, allowing for easy implementation and interaction with the database. The library allows for seamless usage in the client, with automatic procedure renaming and the ability to call methods without generating types. TRPC's client-server interaction is based on HTTP requests and allows for easy debugging and tracing. The library also provides runtime type check and validation using Zod.
Step aside resolvers: a new approach to GraphQL execution
GraphQL Galaxy 2022GraphQL Galaxy 2022
16 min
Step aside resolvers: a new approach to GraphQL execution
GraphQL has made a huge impact in the way we build client applications, websites, and mobile apps. Despite the dominance of resolvers, the GraphQL specification does not mandate their use. Introducing Graphast, a new project that compiles GraphQL operations into execution and output plans, providing advanced optimizations. In GraphFast, instead of resolvers, we have plan resolvers that deal with future data. Graphfast plan resolvers are short and efficient, supporting all features of modern GraphQL.

Workshops on related topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Mastering advanced concepts in TypeScript
React Summit US 2023React Summit US 2023
132 min
Mastering advanced concepts in TypeScript
Top Content
Featured WorkshopFree
Jiri Lojda
Jiri Lojda
TypeScript is not just types and interfaces. Join this workshop to master more advanced features of TypeScript that will make your code bullet-proof. We will cover conditional types and infer notation, template strings and how to map over union types and object/array properties. Each topic will be demonstrated on a sample application that was written with basic types or no types at all and we will together improve the code so you get more familiar with each feature and can bring this new knowledge directly into your projects.
You will learn:- - What are conditional types and infer notation- What are template strings- How to map over union types and object/array properties.
Deep TypeScript Tips & Tricks
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Top Content
Featured Workshop
Josh Goldberg
Josh Goldberg
TypeScript has a powerful type system with all sorts of fancy features for representing wild and wacky JavaScript states. But the syntax to do so isn't always straightforward, and the error messages aren't always precise in telling you what's wrong. Let's dive into how many of TypeScript's more powerful features really work, what kinds of real-world problems they solve, and how to wrestle the type system into submission so you can write truly excellent TypeScript code.
Best Practices and Advanced TypeScript Tips for React Developers
React Advanced 2022React Advanced 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Building Your Own Custom Type System
React Summit 2024React Summit 2024
38 min
Building Your Own Custom Type System
Featured Workshop
Kunal Dubey
Kunal Dubey
I'll introduce the audience to a concept where they can have end-to-end type systems that helps ensure typesafety across the teams Such a system not only improves communication between teams but also helps teams collaborate effectively and ship way faster than they used to before. By having a custom type system, teams can also identify the errors and modify the API contracts on their IDE, which contributes to a better Developer Experience. The workshop would primarily leverage TS to showcase the concept and use tools like OpenAPI to generate the typesystem on the client side. 
Frictionless Development With Unified Type System
JSNation 2024JSNation 2024
113 min
Frictionless Development With Unified Type System
Featured Workshop
Ejiro Asiuwhu
Ejiro Asiuwhu
Imagine developing where frontend and backend sing in harmony, types dance in perfect sync, and errors become a distant memory. That's the magic of TypeScript Nirvana!
Join me on a journey to unveil the secrets of unified type definitions, the key to unlocking frictionless development. We'll dive into:
- Shared language, shared love: Define types once, share them everywhere. Consistency becomes your BFF, errors your worst nightmare (one you'll rarely see).- Effortless coding: Ditch the manual grind of type checking. TypeScript's got your back, freeing you to focus on building awesomeness.- Maintainability magic: With crystal-clear types guiding your code, maintaining it becomes a walk in the park. More time innovating, less time debugging.- Security fortress: TypeScript's type system shields your app from common vulnerabilities, making it a fortress against security threats.