
Lesson Description
The "Generating Types from OpenAPI Contracts" Lesson is part of the full, Fullstack TypeScript, v2 (feat. Zod) course featured in this preview video. Here's what you'd learn in this lesson:
Steve generates TypeScript types from an OpenAPI contract. The types are then imported into the API client app. This not only adds end-to-end type-checking but also validates API route URLs.
Transcript from the "Generating Types from OpenAPI Contracts" Lesson
[00:00:00]
>> Steve Kinney: So let's talk about generating types, right? Just like, hey, I don't wanna have to come up with all this stuff. I want to just be able to generate a bunch of types and have them good and ready to go. So what I'm gonna do is, I'm gonna fire up the terminal.
[00:00:21]
Gotta be in the actual app if you want the shortcuts to work. Cool, and there are a bunch of libraries to do this. Prepare to be amazed. Again, gotta be in the right window or else typing doesn't work. So we can do npx openapi typeScript. So this is one that I use all the time.
[00:00:43]
This is one that I use for our OpenAPI spec at my day job. And I give it the path to the JSON file. And you would probably put this in like an NPM script, right? In my code base, it is NPM run generate types, right? Then you put the output file.
[00:01:06]
In this case, we're gonna say src/, I don't know, api.types.ts. And then you go get a cup of coffee, and you got a little rocket ship and some stars. You feel good, I feel like emoji is the best thing to happen to everything. And we go into the client and open that folder up and go into source and prepare to be at least whelmed, right?
[00:01:39]
On one hand, you didn't have to do any of this yourself. On the other hand, it still is a little bit to be desired. You get this giant, it's actually three types. The paths, which are all the routes and all the information about what they take. And then you get the schemas, which are, in this case, user or tasks in our case.
[00:02:03]
And all the types are just generated for you from the spec, that said, I think if I wanted to do, I'm editing the file says, Do not edit. It's fine, I'm a professional. Task is equal to schemas, no, you'll see why. This leaves something to be desired, but again, you can do it, and it's pretty good.
[00:02:30]
Component schema task, which is a type generated from some JSON schema, which is the right type. Now, you can imagine a large enough code base this can get somewhat insane. But you also have information about what are all the routes, right? So you're to have it autocomplete the routes.
[00:02:51]
You can say, what are the parameters that it takes? Now, will you end up with paths, tasks, parameters? Yes, and I can show you the one I use at work, it gets gnarly. Don't worry, I have another cure coming. But from this standard contract between both sides, you now can generate types based on that contract, and from those types you can generate the schemas.
[00:03:16]
Everything we're doing by hand you can generate. Now, you're like, then why did I do it by hand? Because remember how hard it was to make one of these contracts to begin with that lighter weight thing might be your first thing that you do, right? And you start with that, and then later you can kind of build up to the more robust things.
[00:03:34]
Because if you had to start to have all those schemas, you might get to the point where defining this becomes a lot easier, right? So if you are starting fresh, maybe this makes a ton of sense. If you have tooling that already, or a backend team, that made one of these and you just wanna generate all your types, like yeah, we haven't open it, the backend team made that for me, I just look at it by hand all the time.
[00:03:55]
Well, you can generate your client out of it. So it all depends on what you need to do, but check this out. So that was cool, everyone likes to see that. For my next trick, let's put it in here. API client, where we will grab this import create client.
[00:04:23]
From openapi-fetch, great, awesome, love to see it. And then we need to the import. We just need the type actually, type pass. From those types that we generated. Cool, and now we can do and say const GET, we'll do a batch of them, GET POST, PUT and DELETE, which is create a client at that path.
[00:05:07]
And we're gonna say that the baseUrl, I know it happens to be, obviously, you put this in environment variable, but we're not doing that. 4001, cool, and so all it did, we generate the types based on the open API schema. Great, awesome, cool, right? We grabbed this library and it's literally just taking the types, not even the actual schema or anything like that.
[00:05:39]
So very lightweight because this part will get stripped from the build 'cause types don't get included. And now you can try out stuff where it's like, Get and look, those are my two routes, right? And if I choose that one, right, I can give it a query, And we can see that completed ought to be true.
[00:06:11]
It has basically generated an entire client for making all my API requests from the frontend code, all completely typed for me based on that contract, right? I don't necessarily have to do anything at this point. All the routes get auto completed. If I try to put in a query frame that's not supported.
[00:06:38]
I think those might be optional, so they get ignored, but other pieces. Let's try it on the request body. Cool. Nope, one more curly cube. Here, I think if I put one that's not supported or let's actually just make this- You can see I get the type support to know that can't be null, all right?
[00:07:11]
It's gotta be a stringer undefined. If I make this a number, you get the type safety automatically, sometimes. The optional ones, I think you can have like TypeScript will respect extra properties I think is what the issue is. The ones that are not actually because a body is only those two, TypeScript will ignore all extra properties in any kind of type that you do.
[00:07:41]
It's like one of the nice things about Typescript is if you pass, if it says, I need a property A and B, and you pass one with A, B, and C, and it knows it never uses C, it doesn't yell at you. That way you don't have to strip the properties out of everything, which is great in practice and somewhat annoying when you're trying to make a point in front of friends.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops