Sun Apr 30 2023

The difference between any and unknown in Typescript

A quick expalantion of why and where we would use unknown instead of any

I recently had a chat with a colleague about the difference between using any and unknown in Typescript which really helped me understand them better. 

Consider version 1 below 

1const doSomething = (parameterData: any) => {
2 parameterData();
3};
4doSomething("hello");

Running the above throws a runtime error- parameterData is not a function as the string of “hello” cannot be involved as a function. But we didn't see any red squiggly lines warning us of this issue even before the code was executed as the type any allows anything!

Now we could be forward thinking and check whether the type of parameterData is of type function before invoking it. See version 2 below

1const doSomething = (parameterData: any) => {
2 if (typeof parameterData === "function") {
3 parameterData();
4 }
5};
6const hey = () => {
7 console.log("hey");
8};
9doSomething(hey);

This is better than version 1 as parameterData() will only be executed if it is a function and not anything else. 

But what if someone didn't think about checking if the parameterData is of type function or not? It could lead us to have issues that could have been easily avoided. This is where the type of unknown comes into the picture. 

When we use unknown as below, we see a warning from Typescript telling us that 'parameterData' is of type 'unknown'.

1const doSomething = (parameterData: unknown) => {
2 parameterData();
3 // ^red squiggly line here
4};

To make this go away, we are now tasked with adding a type check here so that our method looks like this now 

1const doSomething = (parameterData: unknown) => {
2 if (typeof parameterData === "function") {
3 parameterData();
4 }
5};

Thanks to the above, parameterData() will now only be executed if it's a function and nothing else. And we were only told to do that thanks to us typing the parameterData parameter as unknown instead of any! So if you expect the parameterData to be a number sometimes in the future, you would need to add another if condition where the typecheck is for a number.

The TLDR version is that when using any to type the type of data, Typescript doesn't give us any warnings. This is pretty bad as why are we even using typescript in the first place? With unknown however, you are asked to do a typecheck on the data that is marked as unknown before performing any operation. This narrows the operations down and only code that is of a certain type is executed. 

Did the above help you understand the difference between any and unknown? Is there anything you’d like to see written about more? Let me know in the comments below!

Comments