Skip to content

Latest commit

 

History

History
461 lines (322 loc) · 15.4 KB

File metadata and controls

461 lines (322 loc) · 15.4 KB

27. TypeScript

[toc]


ℹ️ NOTE: If this works out, a TypeScript Guide may ensue.

27.1. Why TypeScript?

The final chapters of the first unit cover a framework called Angular. Angular runs on TypeScript for a couple of reasons.

First, TypeScript is a superset of JavaScript. That means you can write JavaScript code and use it in TypeScript files.

Second, TypeScript is a statically typed language, that is a language where the type of a varaible is given at the time the program is compiled. This is often achieved by adding the type of the variable to the variable declaration. However, that is no what we have been doing so far. JavaScript is a dynamically typed language, a language where the type of the variable is determined at runtime and is based on the value inside the variable, not the variable declaration.

Statically typed languages are considered to be more stable and less prone to production errors, because the error will occur in development.

27.1.1. Set Up Your Local Development Environment

As we continue to shift away from online work in repl.it (which is a P.I.T.A. to use in the first place) to local development on your computer, you need to install some specific software.

  1. If you haven't done so already: Download and install Visual Studio Code on your computer.
  2. Install Node on your computer, which also installs the NPM CLI. We discussed this briefly bac in the Modules chapter.

REMINDER: If you are using Windows, Chocolatey is the easiest way to install these things. I should have instructions in these notes for doing all this anyway! ( 🎗️TODO: Insert the link to that page later. ​ )

The NPM CLI tool provides you with an efficient and deliberate way to install other software and modules onto your computer. As you proceed through the next four chapters, you will use the NPM CLI in the terminal to perform these installations.

27.2. Declaring and Using Variables

Since TypeScript is statically typed, the type of the value is added to the variabl declaration. However we will still use or let and const keywords where appropriate.

The general format of a variable declaration is:

let variableName : type = value;

27.2.1. number

let variableName : number = 10;

27.2.2. string

let variableName : string = "10";

27.2.3. boolean

let variableName : boolean = true;

27.2.4. Examples

In TypeScript we write:

let spaceShuttleName : string = "Determination";
let shuttleSpeed : number = 17500;
let distanceToMars : number = 225000000;
let distanceToMoon : number = 384400;
let milesPerKilometer : number = 0.621;

which compiles into JavaScript as

let spaceShuttleName = "Determination";
let shuttleSpeed = 17500;
let distanceToMars = 225000000;
let distanceToMoon = 384400;
let milesPerKilometer = 0.621;

27.2.5. Check Your Understanding ✅

27.3. Arrays in TypeScript

Arrays in TypeScript must contain values of the same type. When declaring an array, the type needs to be declared.

let arrayName : number[] = [10,9,8];

What if the array needs to hold values of different types?

Nowe we need a tuple. A tuple is a special structure in TypeScript that can hold as many values needed of different types.

let tupleName: [number, string, number];

tupleName = [10,"9",8];

27.3.1. Examples

🎗️ TODO: Write this section later.

27.3.2. Check Your Understanding ✅

27.4. Functions in TypeScript

When creating functions in TypeScript, we have many of the same options as in JavaScript. We can make anonymous functions, giving them a different number of parameters, etc. However, when working with functions in TypeScript, we have to kee data type in mind.

27.4.1. Declaring Function

27.4.1.1. Named Functions

Let's take a look at a TypeScript function delaration.

Example: We want to declare a function called myFunction with one parameter, a number called x. myFunction returns the value of x multipled by 2.

With this is mind, the declaration in TypeScript would look like:

function myFunction(x : number) : number {
    return x * 2;
}

Here you can see that we provided the type of the paramter and the type of the value returned after the colons. If x were a string or boolean, then we would replace number with the data type of x.

What if the function doesn't return a value? In these cases, we use void as the return type.

Example: Let's change up myFunction a little bit. myFunction still has one parameter, our number called x, however it doesn't return a specific value.

let y : number = 0;

function myFunction(x : number) : void {
    y = x * 2;
}

Instead of returning the value of x multiplied by 2, myFunction now assigns the value of x multipled by 2 to another variable y. We can now use void to specify that no value is returned.

27.4.1.2. Anonymous Functions

For an anonymous function, you still need to privide types for the value returned and the parameters.

Example: Nowe we want to declare an anonymous function myFunction, which has one parameter, a number called x and returns the value of x multipled by 2.

let myFunction = function(x : number) : number { return x * 2; };

Just as we did above with the named function, we need to make sure that we include the data type for the parameters and the return type of the function.

🎗️ TODO: What about arrow functions?

27.4.2. Optional Parameter

In JavaScrit, you can declare a function with 5 parameters and only give it 2 when it comes times to use it. In TypeScript, that is not the case. In TypeScript, when you declare a function with 5 parameters, you have to give the function 5 arguments when calling it, unless you make some of the parameters optional. This means that when you are calling the function, can leave off the optional parameter(s).

To denote a parameter as optional, you can use question mark (?) notation. Any parameters that are optional must follow the required parameters.

Example:

function myFunction(a: number, b?: number): number {
    return a+b+5;
}

console.log(myFunction(1,2));	// 8
console.log(myFunction(1));		// 6
console.log(myFunction(3,5));	// 13
console.log(myFunction(3));		// 8

In this example, the myFunction function has two parameters, a and b. a is required and b is optional. When only one argument is provided to the function, then the value of a+5 is returned. When both arguments are provided, then the sum of the 2 arguments and 4 is returned.

Another way to deal with a parameter you need to be optional is to give a default value.

Let's say that in the example above, we wanted to give b a default value of 5. That way, if no argument is supplied for b, then the value returned is that of a+10.

Example:

function myFunction(a: number, b = 5): number {
    return a+b+5;
}

console.log(myFunction(1,2));	// 8
console.log(myFunction(1));		// 11
console.log(myFunction(3,5));	// 14
console.log(myFunction(3));		// 13

🎗️ TODO: Should b have a type before = 5?

Because b has a default value of 5, when the user does not pass a value to the second argument of myFunction, 5 is used as the value of b.

27.4.3. Check Your Understanding ✅

27.5. Classes and Interfaces in TypeScript

27.5.1. Classes

Classes in TypeScript look something like this:

class Astronaut {
   name: string;
   constructor(firstName: string, lastName: string) {
      this.name = firstName + " " + lastName;
   }
   greet() {
      return "Hello, " + this.name;
   }
}

let Bob = new Astronaut("Bob","Smith");

You may remember the this and new keywords from working with classes in JavaScript. Earlier in the chapter, we also noted that when declaring variables in TypeScript, we have to specify the type of value. The same applies to function parameters, as you can see in the constructor.

When using inheritance, classes in Typescript can also use the extends keyword to denote child and parent classes, as shown here:

class Panthera {
   roar: string;
   constructor(currentRoar: string) {
      this.roar = currentRoar;
   }
}

class Tiger extends Panthera {
   stripes: boolean = true;

}

let tigger = new Tiger("loud");
console.log(tigger.roar);
console.log(tigger.stripes);

27.5.2. Interfaces

Interfaces are not used in JavaScript but are important in TypeScript. Like classes, interfaces define properties and methods that a type will have. The difference is that interfaces do NOT include initialization of properties or implementations of methods.

NOTE: Though the use of interfaces in Angular is not within the scope of this book, interfaces are used rather frequently in Angular code and are important in object-oriented programming languages, such as Java.

We may create an interface for a data type that contains all of the information we need about an astronaut and then used that information in a function.

interface Astronaut {
   name: string;
}

function astronautName (astronaut: Astronaut) {
   name: string;
   return astronaut.name;
}

let bob = {name: "Bob"};
console.log(astronautName(bob));

Interfaces define the contract that other classes or objects must comply with if implementing that interface. Multiple classes can implement one face, and that flexibility allows different classes to share one type. This can be helpful when a function parameter needs to make use of certain behaviors.

interface interfaceName {
   someProperty: number;
}

class className implements interfaceName {
   constructor(x: number) {
      this.someProperty = x;
   }
}

Example:

interface Panthera {
   roar: string;
}

class Tiger implements Panthera {
   roar: string;

   constructor() {
      this.roar = 'rooooaaaarrrr';
   }
}

class Lion implements Panthera {
   roar: string;

   constructor() {
      this.roar = 'ROOOOAAAAARRRRRR';
   }
}

function pantheraSounds(panthera: Panthera) {
   console.log(`Panthera says ${panthera.roar}`);
}

let tiger = new Tiger();
let lion = new Lion();

pantheraSounds(tiger);
pantheraSounds(lion);

In this example, the Panthera interface defines the roar property. Tiger and Lion implement the Panthera interface, which means Tiger and Lion must have a roar property.

The function pantheraSounds has one property of type Panthera. The variables tiger and lion can be passed into pantheraSounds because they are instance of classes that implement the Panthera interface.

27.5.2.1. Optional Parameters

null and undefined are primative data types in TypeScript, however, they are treated differently by TypeScript. If you are planning on using null to define a property of an interface that is not known yet, use the TypeScript optional parameter, ?.

Here's how it would look in TypeScript.

In JavaScript, we might have an object that looks like this:

let giraffeTwo = {
     species: "Reticulated Giraffe",
     name: "Alicia",
     weight: null,
     age: 10,
     diet: "leaves"
};

If we wanted to declare the same object as an interface in TypeScript, we would have to use the optional parameter for the weight property.

interface giraffeTwo = {
     species: string;
     name: string;
     weight?: number;
     age: number;
     diet: string;
};

27.5.3. export

In TypeScript, you can use the export keyword to make classes and interfaces available for import in other files. This will look familiar to you as you saw something similar with modules.

Here's how it is typically used

export class className {
	// properties
	// methods
}

27.5.4. import

In TypeScript, you can use the import keyword to use classes and interfaces declared in other files available for use in the file you are working on. This is a similar idea to importing modules, however, the syntax is different in TypeScript.

import { className } from 'relativeFilePath';

let newClass = new className;

27.5.5. Check Your Understanding ✅

27.6. Compiling TypeScript

To work with TypeScript in our Node environment, we'll need to install the TypeScript module. We talked about running JavaScript in Node. Unlike JavaScript, TypeScript can't be run directly in Node. TypeScript files must be compiled (translated) into JavaScript.

In this section, you will install the compiler and then practice compiling and running a small TypeScript program from the terminal.

==To install TypeScript, type==

$ npm install -g typescript

🍎/ 🐧 Mac/Linux users: You may receive a permission error when running this install command, add sudo to the beginning of the command.

Once you have TypeScript installed, you'll be able to run

$ tsc -v

tsc is the TypeScript compiler. The -v flag will show us the version of TypeScript that we have installed.

27.6.1. hello_world.ts

In true tutorial fashion, let's write a quick Hello, World program so we can see the compiler in action.

In you code editor, create a new file called hello_world.ts. In it, initialize a variable called message with a string value Hello, World, then print the message.

NOTE: Since this is a short program, why not use a simple text edtor like nano or vim?

/* @file hello_world.ts */
let message : string = 'Hello, World';
console.log(message);

In the terminal, navigate to the directory that your hello_world.ts file is in and compile the code.

$ ls
hello_world.ts
$ tsc hello_world.ts
$ ls
hello_world.js hello_world.ts
$ node hello_world.js
Hello, World

If your TypeScript file is free of syntax errors, you won't see a respnse from the terminal directly. However, you should see that you hve a newly generated file in you working directory called hello_world.js.

If it compiles correctly, you should be able to run the hello_world.js file in node and see the classic Hello, World string.

NOTE: If you update you TypeScript file, you must re-compile it so that the changes are applied to the corresponding JavaScript file.

You'll need these compiling and executing steps for the exercises in the following section, so refer back here as needed.

27.7. Exercise: TypeScript 🏃

27.7.1. Part 0 - Get the Starter Code

27.7.2. Part 1 - Declare Variables With Type

27.7.3. Part 2 - Print Days to Mars

27.7.4. Part 3 - Create a Function

27.7.5. Part 4 - Create a Spacecraft Class

27.7.6. Part 5 - Export and Import the SpaceLocation Class

27.7.7. Sanity Check

27.8. Studio: TypeScript 🎙️

27.8.1. Starter Code

27.8.2. Requirements

27.8.3. Classes

27.8.4. Simulation in index.ts

27.8.5. Compile and Run index.ts

27.8.6. Submitting Your Work


#LaunchCode