Our title
, slug
, and markdown
currently have a TypeScript warning on them because they can be of the value FormDataEntryValue
or null
.
To handle this error, we are going to be using invariant
from tiny-invariant to throw warnings if the data being passed isn't a string.
We are also going to type our errors
down in our JSX so they aren't just of type any
.
To do this, we type the errors
variable as ActionData
which will take the title
, slug
, and markdown
as types.
Kent C. Dodds: [0:00] We're going to get the slug, title, and markdown from the post. We'll say, Pick and then, we need a post type. We've got a post type that's in the Prisma client that's generated for us when we update our schema. We're going to import that from the Prisma client.
[0:16] We're going to Pick the slug, title, and markdown so that we can properly create a post. We'll validate that those things are given. Down here, this is giving us a warning. The reason is that the title could actually be a FormDataEntryValue or null. That can happen because users can submit forms that include files, not just strings.
[0:42] We need to verify that the title, slug, and markdown are only a string. To do that, we're going to use invariant from the tiny-invariant library and so, invariant. We'll say typeof title is a string. If it's not, then we'll say, 'title must be a string'. We'll do the same for our slug and markdown.
[1:06] With that, TypeScript knows that the only way for the code to proceed past this line is if the title is a string because invariant tells it so. We know now that the title, slug, and markdown are strings at this point. TypeScript is happy about that.
[1:21] The other thing that would be nice is if this errors object could include the title, slug, and markdown, rather than just being typed as any. We're going to type this as ActionData. We'll create that ActionData up here, similar to the way that we do with LoaderData.
[1:37] We'll say, type ActionData is an object or undefined because if we haven't submitted the form yet, then that ActionData is going to be undefined and the properties of the object are going to be title, slug, and markdown. We'll say title is either null or a string. The slug and markdown are the same.
[1:56] Then, we can actually type this as ActionData. We can use the generic on json, just to make sure that we cover all of our bases. If we have some sort of mistake here, we get some type checking. That gets our TypeScript happy for us. It also makes things a little bit better for us as we're developing our blog.