Annotations and Assertions 12 exercises

The "as" and "as any" Keywords in TypeScript

The error we encountered in this challenge was that the EventTarget | null type was incompatible with the required parameter of type HTMLFormElement. The problem stems from the fact that these types don't match, and null is not permitted:

const data = new FormData(; //

Loading solution


00:00 Okay, let's dive deeper into this area, try to work out what's happening. We can see that new form data requires a HTML form element. This is coming from, again, the DOM typings. And so we can see here. It's basically saying argument of type event target or null is not assignable to a parameter of this type. So first of all, we can look at this and we can say,

00:19 okay, type null is not assignable to HTML form element. So you can't pass null into here. If I were to just pass null, then I would get a similar error. So it would just say argument of type null is not assignable to this. So first of all, we need to say that is not null. So what we could say, this type, if we hover over it here,

00:38 it's an event target. So we could use something interesting here. We could say as event target. Now what as does is it's basically saying this thing at this position, here, we're basically forcing it to be something else.

00:57 And we can see here though, that this isn't working still. Argument of type event target is not assignable to the parameter of type HTML form element. We happen to know that this code is working. It's working at runtime. It's got tests covering it. So what we could say is as HTML form element.

01:15 And notice here, the error now goes away. is now being, even though it's inferred at this position as event target, if we copy this out into its own field here, or own variable, const target equals as HTML form element. Tests are still passing

01:31 and now target is being inferred as HTML form element. How did this happen? This, it's like we're removing some information from TypeScript or kind of, maybe that's the wrong metaphor. What we're saying here is without this annotation, TypeScript is going to infer this as an event target.

01:49 But by saying as HTML form element, we say, no TypeScript, you're wrong. This is actually a HTML form element. We're gonna look at some of the limitations of this going forward, but what we're basically doing is lying to TypeScript or telling it a little white lie so that we can get our runtime working.

02:08 Now, if you can't be bothered to go through that whole process, then there's another way you can get this working even faster, and that is to use any. Now we looked at any a while ago, but as any is often a way that you can basically say, okay, I don't really care what type this is. And at this point, I don't need to know about HTML form elements.

02:28 I can just say as any. And of course, then I can actually just inline this. So I'll just say, oops, where's the thing? Here we go, inline variable. And now we've got as any in that slot. So as any kind of acts as a way of suppressing

02:46 TypeScript errors at this particular point. We're gonna look at a few different caveats with this and how this can spill out and actually cause more bugs. But at this point here, really is just, just being passed directly into this function. And it means that you don't need to worry about that too much.

03:06 But if you have a choice between saying, okay, as any and as HTML form element, this is generally the one you want. You want the more specific one, because this says to TypeScript and to any devs looking at this, this is what I wanted to be.

03:23 Because as any, it sort of doesn't reveal any intention as to the bug you were even trying to fix in the first place. And code bases that I've seen in the wild can contain a lot of as any, just to really patch over TypeScript errors. So you really want to be using it in a very careful way

03:42 and making sure that the thing that you're actually doing is solving the error instead of just making the error go away. So in this case, as HTML form element makes sense, because you're saying to TypeScript, I know more than you about what is going to be. So as is a crucial tool in your tool set,

04:01 because it means you get to annotate with intention, tell TypeScript that you know more than TypeScript does, but you shouldn't be using it as your default way to annotate.