Skip to content

Commit 5984755

Browse files
committed
Write casting not found
1 parent cc5d389 commit 5984755

File tree

3 files changed

+95
-3
lines changed

3 files changed

+95
-3
lines changed
59.9 KB
Loading

content/academy/switching_to_typescript/type_aliases.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,4 @@ We've significantly cleaned up the function by moving its verbose type annotatio
145145

146146
## [](#next) Next up
147147

148-
There is a special type you haven't learned about called `unknown`. We haven't yet discussed it, because it's best learned alongside **typecasting**, which is yet another feature offered by TypeScript. Learn all about the `unknown` type and typecasting in the [next lesson]({{@link switching_to_typescript/unknown_and_type_casting.md}}).
148+
There is a special type you haven't learned about called `unknown`. We haven't yet discussed it, because it's best learned alongside **type casting**, which is yet another feature offered by TypeScript. Learn all about the `unknown` type and typecasting in the [next lesson]({{@link switching_to_typescript/unknown_and_type_casting.md}}).
Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Unknown & type casting
2+
title: Unknown, any, type guards & type casting
33
description: Create your own custom types using the "type" keyword, understand the "void" type, and learn how to write custom function types.
44
menuWeight: 7.6
55
paths:
@@ -8,4 +8,96 @@ paths:
88

99
## [](#unknown-and-type-casting) Unknown & type casting
1010

11-
In the first [**Using types**]({{@link switching_to_typescript/using_types.md}}) lesson, you were briefly exposed to the `any` type.
11+
There are two types we haven't discussed yet - `any` and `unknown`.
12+
13+
## [](#the-any-type) Let's talk about "any"
14+
15+
In the first [**Using types**]({{@link switching_to_typescript/using_types.md}}) lesson, you were briefly exposed to the `any` type, which is a special type used to represent all possible JavaScript values. By using this type, you basically tell TypeScript that you don't care, and that you want to be able to do anything with that value, even if it might cause a runtime error. Take a look at this example:
16+
17+
```TypeScript
18+
// Create a variable that TypeScript will completely ignore.
19+
// Absolutely anything can be stored in here.
20+
let userInput: any;
21+
22+
// Create a variable that can only hold strings
23+
let savedInput: string;
24+
25+
// Set the user input to equal a number. This is fine, because
26+
// it can be any time.
27+
userInput = 5;
28+
29+
// Set the "savedInput" to be the value of "userInput". Stored in
30+
// "userInput" is a number, but since we told TypeScript that it's
31+
// "any" type, an error is not thrown.
32+
savedInput = userInput;
33+
```
34+
35+
Sometimes, `any` can be useful; however, in 99% of cases it is best to avoid it as it can lead to logical errors just like the one above.
36+
37+
## [](#the-unknown-type) Why "unknown" is better
38+
39+
Just like `any`, the `unknown` type is also a special type that represents all possible JavaScript value, and all types are assignable to it. The big difference is that the TypeScript compiler won't allow any operation on values typed as `unknown`. To see this in action, we just have to change the type of `userInput` in the above code snippet from `any` to `unknown`.
40+
41+
![Replacing "any" with "unknown" from the above snippet]({{@asset switching_to_typescript/images/replace-with-unknown.webp}})
42+
43+
Even this will result in the same error:
44+
45+
```TypeScript
46+
// This results in a compiler error!
47+
let userInput: unknown;
48+
let savedInput: string;
49+
50+
userInput = 'hello world!';
51+
52+
savedInput = userInput;
53+
```
54+
55+
## [](#type-guards) Type guards
56+
57+
In order to make the code above not throw any compiler errors, we can use a [type guard](https://www.typescriptlang.org/docs/handbook/advanced-types.html), which is just a check that happens at runtime to ensure that the type is in fact what it should be.
58+
59+
```TypeScript
60+
let userInput: unknown;
61+
let savedInput: string;
62+
63+
userInput = 5;
64+
65+
// This if statement is called a "type guard"
66+
// No more error! TypeScript is smart enough to understand
67+
// what this if statement is doing, and removes the error
68+
if (typeof userInput === 'string') {
69+
savedInput = userInput;
70+
}
71+
```
72+
73+
This works, and in fact, it's the most optimal solution for this use case. But what if we were 100% sure that the value stored in `userInput` was a string? Thats when **type casting** comes in handy.
74+
75+
## [](#type-casting) Type casting
76+
77+
Despite the fancy name, [type casting](https://www.typescripttutorial.net/typescript-tutorial/type-casting/) is a simple concept based around a single keyword: `as`. We usually use this on values that we can't control the return type of, or values that we're sure have a certain type, but TypeScript needs a bit of help understanding that.
78+
79+
```TypeScript
80+
let userInput: unknown;
81+
let savedInput: string;
82+
83+
userInput = 'hello world!';
84+
85+
// No more error! We've told TypeScript to treat "userInput"
86+
// as a string, despite the fact that its original type is
87+
// the "unknown" type
88+
savedInput = userInput as string;
89+
```
90+
91+
## [](#final-thoughts) Final thoughts
92+
93+
Even though you've learned about them in the same lesson, type guards and type casting are inherently very different things with different use cases.
94+
95+
**Type guards** make a runtime check of whether or not a value passes a check that determines that it can be safely used as a certain type. They are great when dealing with values that might hold inconsistent data types (such as user input) where you aren't 100% sure if a certain property will exist.
96+
97+
**Type casting** tells TypeScript to take a value of one type and to treat it as if it were another type. No runtime checks are made. A common use case is casting the response body of an API call (usually has the `any` type depending on what you're using to fetch the data) to a custom type to receive TypeScript support on the data.
98+
99+
Often times, these features are used in tandem.
100+
101+
## [](#next) Next up
102+
103+
some content

0 commit comments

Comments
 (0)