|
1 | 1 | --- |
2 | 2 | id: 67d3018062fe6ba92b7d8299 |
3 | | -title: How Do the Different Types Work in TypeScript? |
| 3 | +title: How Do Primitive Types Work in TypeScript? |
4 | 4 | challengeType: 19 |
5 | | -dashedName: how-do-the-different-types-work-in-typescript |
| 5 | +dashedName: how-do-primitive-types-work-in-typescript |
6 | 6 | --- |
7 | 7 |
|
8 | 8 | # --description-- |
9 | 9 |
|
10 | | -You've already seen one in the previous lesson: `string[]`, which represents an array of strings. But how does that actually work? |
| 10 | +In this lesson, you will learn how to work with basic primitive types and how type annotations work for variables. |
11 | 11 |
|
12 | | -For the primitive data types `string`, `null`, `undefined`, `number`, `boolean`, and `bigint`, TypeScript offers corresponding type keywords. In our example, we are using these types to annotate our variables: |
| 12 | +For the primitive data types `string`, `null`, `undefined`, `number`, `boolean`, and `bigint`, TypeScript offers corresponding type keywords. |
13 | 13 |
|
14 | | -```js |
15 | | -let str: string = "Naomi"; |
16 | | -let num: number = 42; |
17 | | -let bool: boolean = true; |
18 | | -let nope: null = null; |
19 | | -let nada: undefined = undefined; |
20 | | -``` |
| 14 | +For this lesson, we will focus on the commonly used primitives and not go into much detail for `bigint`. The `bigint` data type is a numeric data type in JavaScript to represent numbers larger than the standard integer type. |
21 | 15 |
|
22 | | -Now, we have explicitly declared `str` as `string` - which might seem confusing because we assigned it a string value already, but this annotation ensures that we cannot reassign a different value type (like a number) to that variable. |
| 16 | +Let's take a look at each of these primitive types starting with `string`. Here is how you can type a string in TypeScript: |
23 | 17 |
|
24 | | -But what about arrays and objects? Well, you've already seen the syntax for an array! You can define an array of specific type with two different syntaxes: |
25 | | - |
26 | | -```js |
27 | | -const arrOne: string[] = ["Naomi"]; |
28 | | -const arrTwo: Array<string> = ["Camperchan"]; |
| 18 | +```ts |
| 19 | +let firstName: string = "Angie"; |
29 | 20 | ``` |
30 | 21 |
|
31 | | -Fundamentally, these two syntaxes are the same, and the choice between the two is generally a matter of preference. |
| 22 | +Unlike vanilla JavaScript, the variable `firstName` is expecting a `string` type. So if you try to reassign it with a value of a number, then you will get an error like this: |
32 | 23 |
|
33 | | -Objects get a bit more complicated. You can define the exact structure of an object: |
34 | | - |
35 | | -```js |
36 | | -const obj: { a: string, b: number } = { a: "Naomi", b: 42 }; |
| 24 | +```ts |
| 25 | +let firstName: string = "Angie"; |
| 26 | +firstName = 9 // Type 'number' is not assignable to type 'string'. |
37 | 27 | ``` |
38 | 28 |
|
39 | | -This syntax means that property `a` must always be a string, property `b` must always be a number, and you cannot add or remove properties. |
40 | | - |
41 | | -But maybe you don't want to restrict the properties? Maybe you want an object with any keys, but the values all need to be strings. There are two ways you can do this: |
42 | | - |
43 | | -```js |
44 | | -const objOne: Record<string, string> = {}; |
45 | | -const objTwo: { [key: string]: string } = {}; |
46 | | -``` |
47 | | - |
48 | | -Like the array types, these are fundamentally similar. With these object types, you must define both the type of the keys and the type of the values. Keys must always be strings, but you can define custom string types to further restrict those keys. |
49 | | - |
50 | | -In addition to these types, TypeScript offers four other helpful types. The first is `any`, which indicates that a value can have any type. This is effectively the Konami Code of TypeScript - it tells the compiler to stop caring about the type of that variable and let you do whatever. |
51 | | - |
52 | | -The second is `unknown`, which is generally preferred over `any`. The `unknown` type tells TypeScript that you do care about the type of the value, but you don't actually know what it is. If you then try to perform type-specific actions (like a subtraction operator, or the `slice()` method to perform a specific string operation), TypeScript will expect you to narrow down the type of that value first. You'll learn more about type narrowing in an upcoming lesson. |
| 29 | +The next type we will look at is the `number` type. Here is an example: |
53 | 30 |
|
54 | | -The third is `void`. This is a special type that you'll typically only use when defining functions. It's effectively the opposite of `any` - it represents the absence of any type at all. Functions which don't have a return value, such as `console.log()`, have a return type of `void`. |
55 | | - |
56 | | -Finally, there is the `never` type. This is probably something you won't use often - it represents a type that will never exist. For example, passing a mock object to a function in your test suite might be a good use of `never` to indicate that such an object would never really be passed to the function. |
57 | | - |
58 | | -Expanding on these types, you have access to the `type` keyword. This keyword is like `const`, but instead of declaring a variable you can declare a type: |
59 | | - |
60 | | -```js |
61 | | -type myString = string; |
| 31 | +```ts |
| 32 | +let age: number = 16; |
62 | 33 | ``` |
63 | 34 |
|
64 | | -This might not seem terribly useful on its own, but when coupled with union types it becomes powerful. A union type allows you to combine two or more types into one. Here's an example: |
65 | | - |
66 | | -```js |
67 | | -type stringOrNumber = string | number; |
68 | | -``` |
| 35 | +You can assign integer and floats to the `number` type. But if you were to try and reassign a value that is a `bigint` type, then you will get an error like this: |
69 | 36 |
|
70 | | -Our `stringOrNumber` type matches values that are a string and values that are a number. You can then combine your type with other types, like an array: |
| 37 | +```ts |
| 38 | +let age: number = 16; |
71 | 39 |
|
72 | | -```js |
73 | | -const stuff: stringOrNumber[] = ["a", 2, "c", 1000]; |
| 40 | +// Type 'bigint' is not assignable to type 'number'. |
| 41 | +age = 123n; |
74 | 42 | ``` |
75 | 43 |
|
76 | | -You can also define more strict types that include only specific values: |
| 44 | +The next type we will look at is the `boolean` type. Here are some examples: |
77 | 45 |
|
78 | | -```js |
79 | | -type bot = "camperchan" | "camperbot" | "naomi"; |
80 | | -type digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; |
| 46 | +```ts |
| 47 | +let isLoggedIn: boolean = true; |
| 48 | +let isAdmin: boolean = false; |
81 | 49 | ``` |
82 | 50 |
|
83 | | -You could then combine those types to create more specific restrictions on an object: |
| 51 | +The last two types are the `null` and `undefined` types. |
84 | 52 |
|
85 | | -```js |
86 | | -const artificialIntelligence: Record<bot, digit> = { camperchan: 5 } |
87 | | -``` |
| 53 | +As you recall from earlier JavaScript lessons, `null` represents an intentional absence of a value. `undefined` means a variable has been declared but has not been assigned a value. |
88 | 54 |
|
89 | | -Though if you need more control over the structure of an object, chances are you'll reach for our final type: `interface`. Interfaces are effectively classes, but for types. They can implement or extend other interfaces, are specifically object types, and are generally preferred unless you need a specific feature offered by a type declaration. |
| 55 | +You will see examples of how to work with these types later on when you learn about function types and union types. |
90 | 56 |
|
91 | | -```js |
92 | | -interface wowie { |
93 | | - zowie: boolean; |
94 | | - method: () => void; |
95 | | -} |
96 | | -``` |
| 57 | +Now that you have seen how type annotations work with variables, the question arises on if you need to always explicitly type out your variables. |
97 | 58 |
|
98 | | -Finally, functions can also be given type signatures. In the previous lesson, you saw how to define the type of a particular parameter: |
| 59 | +If you have a simple type annotation like this, then you might not need to use an explicit type. |
99 | 60 |
|
100 | | -```js |
101 | | -const getRandomValue = (array: string[]) => { |
102 | | - return array[Math.floor(Math.random() * array.length)]; |
103 | | -} |
| 61 | +```ts |
| 62 | +let firstName: string = "Angie"; |
104 | 63 | ``` |
105 | 64 |
|
106 | | -But you can also define the return type of the function. |
| 65 | +Reason being is because TypeScript will try to automatically infer the types based on its value. So if you write this, TypeScript will understand it is a string. |
107 | 66 |
|
108 | 67 | ```js |
109 | | -const getRandomValue = (array: string[]): string => { |
110 | | - return array[Math.floor(Math.random() * array.length)]; |
111 | | -} |
| 68 | +let firstName = "Angie"; |
112 | 69 | ``` |
113 | 70 |
|
114 | | -In this example, we've told TypeScript that the function should return a string. If we try to return anything else, TypeScript will provide a compiler error to let us know. |
115 | | - |
116 | | -And that covers the basics of TypeScript's type system. It's pretty complex, and has a lot of moving parts, but it can often help to think of it as mirroring JavaScript's types. |
| 71 | +You should explicitly type your variables when TypeScript cannot clearly infer the type or when you want to enforce a specific type for situations like function parameters or complex objects. |
117 | 72 |
|
118 | 73 | # --questions-- |
119 | 74 |
|
120 | 75 | ## --text-- |
121 | 76 |
|
122 | | -Which of the following is NOT a primitive data type in TypeScript? |
| 77 | +Which of the following is the correct way to explicitly add a type annotation to a number variable? |
123 | 78 |
|
124 | 79 | ## --answers-- |
125 | 80 |
|
126 | | -`string` |
127 | | - |
128 | | -### --feedback-- |
129 | | - |
130 | | -Primitive data types are the most basic data types available in TypeScript. |
| 81 | +```ts |
| 82 | +let age: number = 16; |
| 83 | +``` |
131 | 84 |
|
132 | 85 | --- |
133 | 86 |
|
134 | | -`number` |
| 87 | +```ts |
| 88 | +let age<> number = 16; |
| 89 | +``` |
135 | 90 |
|
136 | 91 | ### --feedback-- |
137 | 92 |
|
138 | | -Primitive data types are the most basic data types available in TypeScript. |
| 93 | +Refer back to the beginning of the lesson for number types. |
139 | 94 |
|
140 | 95 | --- |
141 | 96 |
|
142 | | -`boolean` |
| 97 | +```ts |
| 98 | +let age>> number = 16; |
| 99 | +``` |
143 | 100 |
|
144 | 101 | ### --feedback-- |
145 | 102 |
|
146 | | -Primitive data types are the most basic data types available in TypeScript. |
| 103 | +Refer back to the beginning of the lesson for number types. |
147 | 104 |
|
148 | 105 | --- |
149 | 106 |
|
150 | | -`array` |
| 107 | +```ts |
| 108 | +let age == number = 16; |
| 109 | +``` |
| 110 | + |
| 111 | +### --feedback-- |
| 112 | + |
| 113 | +Refer back to the beginning of the lesson for number types. |
151 | 114 |
|
152 | 115 | ## --video-solution-- |
153 | 116 |
|
154 | | -4 |
| 117 | +1 |
155 | 118 |
|
156 | 119 | ## --text-- |
157 | 120 |
|
158 | | -What is the purpose of the `unknown` type in TypeScript? |
| 121 | +Which of the following is NOT a primitive data type? |
159 | 122 |
|
160 | 123 | ## --answers-- |
161 | 124 |
|
162 | | -It allows any type of value to be assigned without type checking. |
| 125 | +`string` |
163 | 126 |
|
164 | 127 | ### --feedback-- |
165 | 128 |
|
166 | | -Unlike `any`, `unknown` requires type narrowing before specific operations can be performed. |
| 129 | +Refer back to the beginning of the lesson. |
167 | 130 |
|
168 | 131 | --- |
169 | 132 |
|
170 | | -It indicates that you don't know the type and need to narrow it before use. |
| 133 | +`boolean` |
171 | 134 |
|
172 | | ---- |
| 135 | +### --feedback-- |
173 | 136 |
|
174 | | -It represents the absence of any type at all. |
| 137 | +Refer back to the beginning of the lesson. |
175 | 138 |
|
176 | | -### --feedback-- |
| 139 | +--- |
177 | 140 |
|
178 | | -Unlike `any`, `unknown` requires type narrowing before specific operations can be performed. |
| 141 | +`object` |
179 | 142 |
|
180 | 143 | --- |
181 | 144 |
|
182 | | -It represents a type that will never exist. |
| 145 | +`number` |
183 | 146 |
|
184 | 147 | ### --feedback-- |
185 | 148 |
|
186 | | -Unlike `any`, `unknown` requires type narrowing before specific operations can be performed. |
| 149 | +Refer back to the beginning of the lesson. |
187 | 150 |
|
188 | 151 | ## --video-solution-- |
189 | 152 |
|
190 | | -2 |
| 153 | +3 |
191 | 154 |
|
192 | 155 | ## --text-- |
193 | 156 |
|
194 | | -Which keyword is used to declare a custom type in TypeScript? |
| 157 | +When should you explicitly type your variables in TypeScript? |
195 | 158 |
|
196 | 159 | ## --answers-- |
197 | 160 |
|
198 | | -`interface` |
| 161 | +When you are working with `number` and `bigint` types. |
199 | 162 |
|
200 | 163 | ### --feedback-- |
201 | 164 |
|
202 | | -This keyword is used to define a contract for object shapes, not to declare custom types. |
| 165 | +Refer back to the end of the lesson. |
203 | 166 |
|
204 | 167 | --- |
205 | 168 |
|
206 | | -`type` |
| 169 | +When you are working with `null` and `undefined` types. |
207 | 170 |
|
208 | | ---- |
| 171 | +### --feedback-- |
209 | 172 |
|
210 | | -`custom` |
| 173 | +Refer back to the end of the lesson. |
211 | 174 |
|
212 | | -### --feedback-- |
| 175 | +--- |
213 | 176 |
|
214 | | -This is not a valid keyword in TypeScript. |
| 177 | +When TypeScript cannot clearly infer the type. |
215 | 178 |
|
216 | 179 | --- |
217 | 180 |
|
218 | | -`define` |
| 181 | +You should always have explicit types in your code. |
219 | 182 |
|
220 | 183 | ### --feedback-- |
221 | 184 |
|
222 | | -This is not a valid keyword in TypeScript. |
| 185 | +Refer back to the end of the lesson. |
223 | 186 |
|
224 | 187 | ## --video-solution-- |
225 | 188 |
|
226 | | -2 |
| 189 | +3 |
0 commit comments