-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
364 additions
and
3 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# TypeScript: Classes | ||
|
||
## Start Simple | ||
|
||
```ts | ||
class Greeter { | ||
greeting: string; | ||
constructor(message: string) { | ||
this.greeting = message; | ||
} | ||
greet() { | ||
return "Hello, " + this.greeting; | ||
} | ||
} | ||
|
||
let greeter = new Greeter("world"); | ||
``` | ||
|
||
They also do inheritance: | ||
|
||
```ts | ||
class Animal { | ||
move(distanceInMeters: number = 0) { | ||
console.log(`Animal moved ${distanceInMeters}m.`); | ||
} | ||
} | ||
|
||
class Dog extends Animal { | ||
bark() { | ||
console.log('Woof! Woof!'); | ||
} | ||
} | ||
|
||
const dog = new Dog(); | ||
dog.bark(); | ||
dog.move(10); | ||
dog.bark(); | ||
``` | ||
|
||
|
||
Etc. You know that from ES6. | ||
|
||
## Public, private and protected | ||
|
||
### Public | ||
|
||
In TS everything inside class is public by default: | ||
|
||
```ts | ||
class Animal { | ||
public name: string; | ||
public constructor(theName: string) { this.name = theName; } | ||
public move(distanceInMeters: number) { | ||
console.log(`${this.name} moved ${distanceInMeters}m.`); | ||
} | ||
} | ||
|
||
``` | ||
|
||
In order to freely call the methods and vars. | ||
|
||
|
||
### Private | ||
|
||
Private methods and props cannot be accessed outside of the class. | ||
|
||
```ts | ||
class Animal { | ||
private name: string; | ||
constructor(theName: string) { this.name = theName; } | ||
} | ||
|
||
new Animal("Cat").name; // Error: 'name' is private; | ||
``` | ||
|
||
```ts | ||
class Animal { | ||
private name: string; | ||
constructor(theName: string) { this.name = theName; } | ||
} | ||
|
||
class Rhino extends Animal { | ||
constructor() { super("Rhino"); } | ||
} | ||
|
||
class Employee { | ||
private name: string; | ||
constructor(theName: string) { this.name = theName; } | ||
} | ||
|
||
let animal = new Animal("Goat"); | ||
let rhino = new Rhino(); | ||
let employee = new Employee("Bob"); | ||
|
||
animal = rhino; | ||
animal = employee; // Error: 'Animal' and 'Employee' are not compatible | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
# TypeScript Functions | ||
|
||
We can use both anonimous and named funcs: | ||
|
||
```ts | ||
// Named function | ||
function add(x, y) { | ||
return x + y; | ||
} | ||
|
||
// Anonymous function | ||
let myAdd = function(x, y) { return x + y; }; | ||
``` | ||
|
||
Let's rewrite that: | ||
|
||
```ts | ||
function add(x: number, y: number): number { | ||
return x + y; | ||
} | ||
|
||
let myAdd = function(x: number, y: number): number { return x + y; }; | ||
``` | ||
|
||
|
||
## Optional | ||
|
||
We can set value as optional using `?`, then it would be equal to `undefined` | ||
|
||
```ts | ||
function buildName(firstName: string, lastName?: string) { | ||
if (lastName) | ||
return firstName + " " + lastName; | ||
else | ||
return firstName; | ||
} | ||
|
||
let result1 = buildName("Bob"); // works correctly now | ||
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters | ||
let result3 = buildName("Bob", "Adams"); // ah, just right | ||
``` | ||
|
||
But there are still default params: | ||
|
||
```ts | ||
function buildName(firstName: string, lastName = "Smith") { | ||
// ... | ||
} | ||
``` | ||
|
||
## Rest params | ||
|
||
```ts | ||
function buildName(firstName: string, ...restOfName: string[]) { | ||
return firstName + " " + restOfName.join(" "); | ||
} | ||
|
||
// employeeName will be "Joseph Samuel Lucas MacKinzie" | ||
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie"); | ||
``` | ||
|
||
## this | ||
|
||
Let's try example: | ||
|
||
```ts | ||
let deck = { | ||
suits: ["hearts", "spades", "clubs", "diamonds"], | ||
cards: Array(52), | ||
createCardPicker: function() { | ||
return function() { | ||
let pickedCard = Math.floor(Math.random() * 52); | ||
let pickedSuit = Math.floor(pickedCard / 13); | ||
|
||
return {suit: this.suits[pickedSuit], card: pickedCard % 13}; | ||
} | ||
} | ||
} | ||
|
||
let cardPicker = deck.createCardPicker(); | ||
let pickedCard = cardPicker(); | ||
|
||
alert("card: " + pickedCard.card + " of " + pickedCard.suit); | ||
``` | ||
|
||
In this case we will get an error, as `deck.createCardPicker`'s `this` would call not `deck`, but `window`, because we call `cardPicker` on its own | ||
|
||
To make sure we would call `deck`, we can just use ES6 arrows: | ||
|
||
```ts | ||
let deck = { | ||
suits: ["hearts", "spades", "clubs", "diamonds"], | ||
cards: Array(52), | ||
createCardPicker: function() { | ||
// NOTE: the line below is now an arrow function, allowing us to capture 'this' right here | ||
return () => { | ||
let pickedCard = Math.floor(Math.random() * 52); | ||
let pickedSuit = Math.floor(pickedCard / 13); | ||
|
||
return {suit: this.suits[pickedSuit], card: pickedCard % 13}; | ||
} | ||
} | ||
} | ||
|
||
let cardPicker = deck.createCardPicker(); | ||
let pickedCard = cardPicker(); | ||
|
||
alert("card: " + pickedCard.card + " of " + pickedCard.suit); | ||
``` | ||
|
||
But no. `this.suits[pickedSuit]` is still `any` type. It is easily fixable in arguments: | ||
|
||
```ts | ||
function f(this: void) { | ||
// make sure `this` is unusable in this standalone function | ||
} | ||
``` | ||
|
||
Let's make it readable: | ||
|
||
```ts | ||
interface Card { | ||
suit: string; | ||
card: number; | ||
} | ||
interface Deck { | ||
suits: string[]; | ||
cards: number[]; | ||
createCardPicker(this: Deck): () => Card; | ||
} | ||
let deck: Deck = { | ||
suits: ["hearts", "spades", "clubs", "diamonds"], | ||
cards: Array(52), | ||
// NOTE: The function now explicitly specifies that its callee must be of type Deck | ||
createCardPicker: function(this: Deck) { | ||
return () => { | ||
let pickedCard = Math.floor(Math.random() * 52); | ||
let pickedSuit = Math.floor(pickedCard / 13); | ||
|
||
return {suit: this.suits[pickedSuit], card: pickedCard % 13}; | ||
} | ||
} | ||
} | ||
|
||
let cardPicker = deck.createCardPicker(); | ||
let pickedCard = cardPicker(); | ||
|
||
alert("card: " + pickedCard.card + " of " + pickedCard.suit); | ||
``` | ||
|
||
## Overloads | ||
|
||
```ts | ||
let suits = ["hearts", "spades", "clubs", "diamonds"]; | ||
|
||
function pickCard(x): any { | ||
// Check to see if we're working with an object/array | ||
// if so, they gave us the deck and we'll pick the card | ||
if (typeof x == "object") { | ||
let pickedCard = Math.floor(Math.random() * x.length); | ||
return pickedCard; | ||
} | ||
// Otherwise just let them pick the card | ||
else if (typeof x == "number") { | ||
let pickedSuit = Math.floor(x / 13); | ||
return { suit: suits[pickedSuit], card: x % 13 }; | ||
} | ||
} | ||
|
||
let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }]; | ||
let pickedCard1 = myDeck[pickCard(myDeck)]; | ||
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit); | ||
|
||
let pickedCard2 = pickCard(15); | ||
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit); | ||
``` | ||
|
||
|
||
And you can rewrite things. Sorry pals, this isn't very clever |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# TypeScript: Generics | ||
|
||
## Hello World | ||
|
||
Without generics ping would look like: | ||
|
||
```ts | ||
const ping = (arg: number): number => arg; | ||
``` | ||
|
||
And here is _type variable_ generic: | ||
|
||
```ts | ||
const ping<T> = (arg: T): T => (arg); | ||
``` | ||
|
||
So `T` catches a type of user input in order to use it later on. | ||
|
||
Once we’ve written the generic зштп function, we can call it in one of two ways. The first way is to pass all of the arguments, including the type argument, to the function: | ||
|
||
```ts | ||
let out = ping<string>(" PONG! "); | ||
``` | ||
|
||
Or we can skip manual generic set: | ||
|
||
```ts | ||
let out = ping(" PONG! "); | ||
``` | ||
|
||
Compiler will auto-detect type. | ||
|
||
## More Generic Type Variables | ||
|
||
`T` unlike any doesn't forgive your any-ness: | ||
|
||
```ts | ||
const aboutNumbers<T> = (arg: T): T => { | ||
console.log(arg.length); //ERROR: T doesn't have length | ||
return arg; | ||
} | ||
``` | ||
|
||
Let's pretend we really want it to be arrays of `T` instead of T, then simple fix: | ||
|
||
```ts | ||
const aboutNumbers<T> = (arg: T[]): T[] => { | ||
console.log(arg.length); | ||
return arg; | ||
} | ||
``` | ||
|
||
Or like this: | ||
|
||
```ts | ||
const aboutNumbers<T> = (arg: Array<T>): Array<T> => { | ||
console.log(arg.length); | ||
return arg; | ||
} | ||
``` | ||
|
||
But hey, we can create our own generic types, like that `Array<T>`: | ||
|
||
## Generic Types | ||
|
||
So let's make our interface: | ||
|
||
```ts | ||
interface GenericPing{ | ||
<T>(arg: T): T; | ||
} | ||
|
||
const ping<T> = (arg: T): T => (arg); | ||
|
||
let pingpong: GenericPing = ping; | ||
``` | ||
|
||
Or we can even add a generic type for our interface: | ||
|
||
```ts | ||
let pingpong: GenericPing<number> = ping; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters