Skip to content

Commit

Permalink
Merge pull request #220 from developedbysaad/update-scripts
Browse files Browse the repository at this point in the history
Update L2 scripts
  • Loading branch information
reenas authored Oct 25, 2023
2 parents 332dcce + 138bdd7 commit 7ffa02b
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 58 deletions.
23 changes: 14 additions & 9 deletions typescript-fundamentals/adding-typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@ In this lesson, let us work to integrate TypeScript and make it work with our ex

Follow the steps below to ensure the existing application created in the previous level, `hello-react` is migrated to TypeScript.

- Install TypeScript:
Open your terminal and navigate to the root folder of our project.
## Install TypeScript:

Run the following command:
Open your terminal and navigate to the root folder of our project.

> Action: Run the following command:
```
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
```

This will install TypeScript and related packages as a development dependency of your project.

- Rename files:
In the `src` folder of your project, rename any files you have created with a `.js/.jsx` extension to `.tsx`.
This tells TypeScript to treat those files as TypeScript files.
## Rename files:

In the `src` folder of your project, rename any files you have created with a `.js/.jsx` extension to `.tsx`.
This tells TypeScript to treat those files as TypeScript files.

## Configure TypeScript:

Create a new file named `tsconfig.json` in the root folder of your project if it is not already created.
Add the following code to `tsconfig.json`:

- Configure TypeScript:
Create a new file named `tsconfig.json` in the root folder of your project if it is not already created.
Add the following code to `tsconfig.json`:
> Action: Paste the following code in `tsconfig.json`
```js
{
Expand Down
60 changes: 40 additions & 20 deletions typescript-fundamentals/arrays-and-tuples-in-ts/README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,74 @@
In this lesson, let us discuss what Arrays and Tuples are in Typescript and how to use them in your code.
In this lesson, we'll dive into Arrays and Tuples in TypeScript, learning how to work with collections of data and ordered lists of fixed data types.

## Arrays
## Arrays in TypeScript

Arrays in TypeScript are a data type that allows you to store a collection of elements, typically of the same type. To create an array in TypeScript, you can use the syntax `let arrayName: type[] = [value1, value2, ..., valueN]`, where `arrayName` is the name you want to give to your array, type is the type of the elements in the array, and `value1`, `value2`, ..., `valueN` are the values of the elements in the array.
Arrays are an essential data type in TypeScript. They allow you to store a collection of elements, typically of the same type. To create an array in TypeScript, you can use the following syntax:

For example:
> Action: Display the following snippet of code on Screen
```js
```javascript
let arrayName: type[] = [value1, value2, ..., valueN];
```

Where `arrayName` is the name of your array, `type` is the type of elements in the array, and `value1`, `value2`, ..., `valueN` are the actual values.

Let's create arrays in TypeScript.

> Action: Paste the following snippet of code in `main.ts` file
```javascript
let projectID: number[] = [1, 2, 3, 4, 5];
let taskList: string[] = ["Fix Camera", "Buy Milk"];
```

In the first line, we create an array of numbers called `numbers`. In the second line, we create an array of strings called `strings`.
Here, we have `projectID` as an array of numbers and `taskList` as an array of strings. TypeScript ensures that you can only add elements of the specified type to the array.

## Type Safety in Arrays

As the array can only hold one specific type of data, trying to modify any data with a different data type will throw an error in typescript.
TypeScript's type safety extends to arrays. If you attempt to modify an array element with a different data type, TypeScript will catch it.

For example:
> Action: Paste the following snippet of code in `main.ts` file
```js
```javascript
projectID[0] = "Make food"; // TypeScript will give an error here
taskList[1] = 5; // TypeScript will give an error here
```

The above statements will result in a Typescript compilation error.
These statements result in TypeScript compilation errors, which help you maintain data integrity.

Arrays in TypeScript are helpful when storing elements of the same type. They allow you to work with basic JavaScript arrays with added safety built-in.
## Tuples in TypeScript

## Tuples

Tuples in TypeScript are similar to arrays, but unlike arrays, which can store elements of different types, tuples can store elements of fixed data types. In other words, a tuple is an ordered list of a fixed number of elements, where each element has a specific type.
Tuples in TypeScript are like arrays, but with a crucial difference: they store elements of fixed data types. A tuple is an ordered list with a specific type for each element.

To create a tuple in TypeScript, you can use the syntax

```js
> Action: Display the following snippet of code on Screen
```javascript
let tupleName: [type1, type2, ..., typeN] = [value1, value2, ..., valueN]
```

For example, to create a tuple named `user` that holds a `username (string)` and a `password (string)`, you can use the following code:
For example, to create a tuple named user that holds a username (string) and a password (string), you can use the following code:

> Action: Paste the following snippet of code in `main.ts` file
```js
```javascript
let user: [string, string] = ["johnDoe", "mySecretPassword"];
```

You can also use the below way to easily extract the values of the elements in a tuple into separate variables. For example, to extract the `username` and `password` from the `user` tuple, you can use the following code:
## Destructuring Tuples

In TypeScript, you can easily extract values from a tuple into separate variables using destructuring.

For example, to extract the username and password from the user tuple, you can use the following code:

> Action: Destructuring a tuple.
```js
```javascript
let [username, password] = user;
```

This is called **destructuring** and helps in extracting the data from the Tuple.
This is called destructuring and helps in extracting the data from the Tuple.

In the upcoming lessons, you will be using the above data types to add functionality to your application that is error free to implement.

Expand Down
50 changes: 36 additions & 14 deletions typescript-fundamentals/datatypes-in-typescript/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,66 @@
In this lesson, we will learn about the `any`, `void` and `never` data types in TypeScript. The `any` data type is a special type that can be used to opt out of TypeScript's type-checking system. It's useful in cases where you don't know the type of value ahead of time, or where you want to disable type-checking for a specific variable or expression. The `void` and `never` data types are used to represent the absence of a value.
In this lesson, we'll dive into TypeScript's data types. Specifically, we'll explore the `any`, `void`, and `never` data types and understand how they work.

To use the `any` data type, you simply need to annotate the variable or expression with any. For example, try writing the following code in your `main.ts`:
## Understanding `any` Data Type

```js
The `any` data type is a unique one. It's like a wildcard that allows us to escape TypeScript's type-checking system. This is handy when you don't know the type of a value in advance or when you intentionally want to bypass type-checking for a specific variable or expression.

Let's see how to use the `any` data type in code.

> Action: Write the following code in `main.ts` file:
```javascript
let name: any = "hello";
name = 42;
name = false;
```

In this example, the variable `name` is declared as type `any`, which means it can hold any type of value. As a result, we can assign it a `string`, a `number`, and a `boolean` value without any errors being thrown.
In this code, we declare the `name` variable with the type `any`. This means it can hold values of any type, be it a string, number, or boolean. TypeScript won't complain, even though we're switching data types.

## Exploring the `void` Data Type

Next up, we have the `void` data type. It represents the absence of a value and is often used as the return type of functions that don't return anything.

Let's add a `void` function to our code

The `void` type represents the absence of any type. It is commonly used as the return type of function that does not return a value. Add the below code to your `main.ts` file:
> Action: Add the below code to your main.ts file:
```js
```javascript
function printHello(): void {
console.log("Hello!");
}
```

In this example, the `printHello` function does not return a value, so its return type is `void`. If we try to return a value from this function, TypeScript will give us an error:
In this example, the `printHello` function doesn't return any value, so we mark it with the `void` type. If you try to return something from a `void` function, TypeScript will raise an error.

```js
```javascript
function printHello(): void {
console.log("Hello!");
return "hello"; // TypeScript will give an error here
}
```

The `never` type represents the absence of a value, but it indicates that the function will never return. This is useful for representing functions that throw an error or never terminate. Add the below code to your `main.ts` file:
## The `never` Data Type

```js
Lastly, we have the `never` data type. It signifies the absence of a value and implies that a function will never return. This is particularly useful for functions that either throw errors or run infinitely.

Let's add a function using the `never` type.

> Action: Paste the following snippet of code into your `main.ts` file.
```javascript
function throwError(): never {
throw new Error("An error occurred!");
}
```

In this example, the `throwError` function never returns because it always throws an error. Therefore, its return type is `never`.
In the `throwError` function, it's clear that it will never return normally because it always throws an error. Therefore, its return type is `never`.

## Important Considerations

Keep in mind that while the `any` data type is versatile, it can also compromise the benefits of using TypeScript, such as improved code reliability and maintainability. Thus, it's advisable to use it sparingly, only when absolutely necessary.

It's important to note that using the `any` data type can disable many of the benefits of using TypeScript, such as improved code reliability and better code maintainability. As a result, it's generally best to restrict the use of `any` data type to a minimum and only when absolutely necessary.
By understanding and using these data types in TypeScript, you can catch errors early, ensuring that your code functions as intended and is more robust.

Using these types in TypeScript can help you catch errors in your code and ensure that your functions are working as intended.
## Conclusion

See you in the next lesson!
That's it for this lesson! You've now learned about the `any`, `void`, and `never` data types in TypeScript. These concepts are fundamental to writing type-safe and reliable code in your ReactJS and TypeScript projects. Stay tuned for the next lesson!
20 changes: 19 additions & 1 deletion typescript-fundamentals/ts-interfaces/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ An interface in TypeScript is a type that defines a contract for the shape of an

For example, consider an interface for a `User` object that has a `name` property of type `string`, an `id` property of type `number`, and a function, `greet()`, that returns a `string`. Here is how we can define this interface:

> Action: Paste the following snippet of code in main.ts
```js
interface User {
name: string;
Expand All @@ -14,6 +16,10 @@ interface User {

We can then use this interface to create an object that adheres to this contract:

Let's create a `User` object.

> Action: Paste the following snippet of code in main.ts
```js
const user: User = {
name: "Alice",
Expand All @@ -24,16 +30,22 @@ const user: User = {
};
```

If we try to create an object that does not have the required properties, or if the properties have the wrong types, we will get a TypeScript error.
With this, our `user` object meets the `User` interface's requirements. If we tried to create an object that doesn't fulfill these requirements or contains properties of the wrong types, TypeScript would provide an error.

> Action: Paste the following snippet of code in `main.ts` file.
```js
const user: User = { name: "Alice" }; // Error: Property 'id' is missing in type '{ name: string; }'

const user: User = { name: "Alice", id: "10" }; // Error: Type 'string' is not assignable to type 'number'
```

For example If you'll try executing this snippet of you'll be see the error messages which i have written down in comments.

We can also use interfaces to define the shape of function arguments and return values. For example, here is an interface for a function that takes a User object and returns a string:

> Action: Paste the following snippet of code in `main.ts` file.
```js
interface GetGreetingFn {
(user: User): string;
Expand All @@ -42,6 +54,8 @@ interface GetGreetingFn {

We can then create a function that adheres to this contract:

> Action: Paste the following snippet of code in `main.ts` file.
```js
const getGreeting: GetGreetingFn = (user: User) => {
return user.greet();
Expand All @@ -52,6 +66,8 @@ console.log(getGreeting(user)); // "Hello, my name is Alice"

Interfaces can also be used to define the shape of classes. For example, we can define an interface for an `Employee` class that extends the `User` interface and has a salary property of type `number`:

> Action: Paste the following snippet of code in `main.ts` file.
```js
interface Employee extends User {
salary: number;
Expand All @@ -60,6 +76,8 @@ interface Employee extends User {

We can then create a class that implements this interface:

> Action: Paste the following snippet of code in `main.ts` file.
```js
class Manager implements Employee {
name: string;
Expand Down
34 changes: 20 additions & 14 deletions typescript-fundamentals/type-annotations-and-inference/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
In this lesson, we'll cover what type annotations and inference are and how they are used in TypeScript.
In this lesson, we'll explore two essential concepts in TypeScript: `Type Annotations` and `Type Inference`, and understand how they are used to make your code more robust and self-documenting.

TypeScript being a superset of JavaScript introduces several features that are not available in JavaScript, such as static typing and type annotations.
## Type Annotations

Type annotations allow you to specify the expected data type of the function's arguments and return value. This can help make your code more self-documenting and prevent certain types of runtime errors.
Type Annotations in TypeScript allow you to explicitly specify the expected data types of function arguments and return values. This not only makes your code more self-documenting but also helps prevent certain types of runtime errors.

For example, let's consider the following function that takes in the details of a user and returns a success message as a string. Add the below code to the `main.ts` where we have the interface for the User defined:
Let's consider an example with type annotations.

```js
> Action: Paste the following snippet of code in `main.ts` file.
```javascript
function addUser(user: User): string {
return user.name + " added successfully";
}
```

Here, we have used type annotations to specify that the `addUser` function takes in an input which follows the interface User and returns a string.
In this code, we've used type annotations to declare that the `addUser` function expects an argument following the `User` interface and will return a `string`. This clarity in our code helps us catch type-related issues early.

Type annotations are optional in TypeScript, and you can use them even if you don't have a type-checker installed. You can perform static type-checking to ensure that your code is type-safe.
Type annotations are optional in TypeScript, even without a type-checker installed. You can still use them for static type-checking, ensuring your code is type-safe.

Now, let's move on to type inference.
## Type Inference

In TypeScript, type inference refers to the ability of the compiler to automatically determine the data type of a value based on its usage. This means that you don't have to explicitly specify the types of variables and expressions in your code, and the compiler will infer their types for you.
Type Inference in TypeScript refers to the compiler's ability to automatically deduce the data type of a value based on its usage. This means you don't always need to explicitly specify variable or expression types; the compiler can figure them out for you.

For example, consider the following code:
> Action: Let's see type inference in action.
```js
```javascript
let userName = "Jane"; // type: string
let userID = 10; // type: number
let uniqueID = userName + userID;
```

Here, the compiler will automatically infer that `userName` is a string and `userID` is a number and will concatenate the final output as a string.
In this code, the TypeScript compiler automatically infers that `userName` is of type `string`, `userID` is of type `number`, and `uniqueID` becomes a string. This simplifies your code while ensuring type safety.

## Combining Annotations and Inference

By combining Type Annotations and Type Inference, you can write clean, self-documenting code that's also type-safe. Use annotations where clarity is essential, and let inference do the heavy lifting when types are obvious.

By using type annotations and type inference together, you can write clean, self-documenting code that is also type-safe.
## Conclusion

See you in the next lesson!
That wraps up our lesson on TypeScript Type Annotations and Inference. These concepts are fundamental for writing type-safe and clear code in your ReactJS and TypeScript projects. Stay tuned for the next lesson where we'll dive into more TypeScript goodness!

0 comments on commit 7ffa02b

Please sign in to comment.