Created
October 27, 2018 12:06
-
-
Save tkssharma/52060fb1c3a49222a3be95dc8789cb48 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
function switchFunction(num: number) { | |
let b: string = "functionb"; | |
switch (num) { | |
case 1: { | |
let b: string = "case 1"; | |
break; | |
} // After break | |
case 2: | |
{ | |
let b: string = "case 2"; | |
} // Before break | |
break; | |
} | |
} | |
const arr: number[] = [1, 2, 3]; | |
arr.push(4); | |
const myObj: { x: number } = { x: 1 }; | |
myObj.x = 2; | |
let n2: string | undefined = Math.random() > 0.5 ? undefined : "test"; | |
// console.log(n2.substring(0, 1)); // Won't compile since can be null | |
if (n2 !== null) { | |
console.log(n2.substring(0, 1)); | |
} | |
function f1(optional?: string): void { | |
if (optional === undefined) { | |
// Optional parameter was not provided OR was set to undefined | |
} else { | |
// The optional parameter is for sure a string (not undefined) | |
} | |
} | |
let primitiveWithUndefined: number | undefined = undefined; | |
function functOptionalArg(primitiveOptional?: number): void { | |
// ... | |
} | |
functOptionalArg(); | |
functOptionalArg(undefined); | |
functOptionalArg(1); | |
// The non-primitive group includes void, string literal, tuple, any, unknown, and never | |
function returnNever(i: number): never { | |
// Logic here | |
if (i === 0) { | |
throw Error("i is zero"); | |
} else { | |
throw Error("i is not zero"); | |
} | |
// Will never reach the end of the function | |
} | |
//-----------------------------------------// | |
type myUnion = "a" | "b"; | |
function elseNever(value: myUnion) { | |
if (value === "a") { | |
value; // type is “a” | |
} else if (value === "b") { | |
value; // type is “b” | |
} else { | |
value; // type is never | |
} | |
} | |
// enforcing types in a List | |
let arrayWithSquareBrackets: number[] = [1, 2, 3]; | |
let arrayWithObject: Array<number> = [1, 2, 3]; | |
let arrayWithObjectNew: Array<number> = new Array<number>(1, 2, 3); | |
let arrayWithSquareBrackets2: (number | string)[] = [1, 2, "one", "two"]; | |
let arrayWithObject2: Array<number | string> = [1, 2, "one", "two"]; | |
enum Weather { | |
Sunny, | |
Cloudy, | |
Rainy, | |
Snowy | |
} | |
let today: Weather = Weather.Cloudy; | |
let tomorrow: Weather = 200; | |
console.log("Today value", today); // Today value Cloud | |
console.log("Today key", Weather[today]); // Today key undefined | |
enum Weather1 { | |
Sunny = 100, | |
Cloudy, | |
Rainy = 200, | |
Snowy | |
} | |
//---------------------------------------------------// | |
interface Book { | |
type: "book"; | |
isbn: string; | |
page: number; | |
} | |
interface Movie { | |
type: "movie"; | |
lengthMinutes: number; | |
} | |
let hobby: Movie = { type: "movie", lengthMinutes: 120 }; | |
function showHobby(hobby: Book | Movie): void { | |
if (hobby.type === "movie") { | |
console.log("Long movie of " + hobby.lengthMinutes); | |
} else { | |
console.log("A book of few pages: " + hobby.page); | |
} | |
} | |
// ---------------------------------------// | |
function funct3(param1: boolean | string): void {} | |
function funct2(param1: boolean, param2: string): void {} | |
function funct4(): string | number | boolean { | |
return ""; | |
} | |
function funct5(param1: boolean): string; | |
function funct5(param1: Date): number; | |
function funct5(param1: boolean | Date): string | number { | |
if (typeof param1 === "boolean") { | |
return param1 ? "Yes" : "No"; | |
} else { | |
return 0; | |
} | |
} | |
class hello { | |
private long: (p1: number) => string = (p1: number) => { | |
return ""; | |
}; | |
private short: (p1: number) => string = p1 => ""; | |
private tiny = (p1: number) => ""; | |
} | |
/* | |
TypeScript and map | |
The difference between an index signature and a map | |
The difference between object and Object | |
When to use object, Object, or any | |
What is an object literal | |
How to create a constructed object | |
The difference between an explicit type or a cast | |
Variable with many types | |
Combining a type with an intersection | |
Intersecting with something other than a type | |
Intersecting with an optional type | |
Merging a type with inheritance | |
The difference between a type and an interface | |
Destructuring a type and an array | |
*/ | |
let map2 = new Map(); // Key any, value any | |
let map3 = new Map<string, number>(); // Key string, value number | |
//let map4 = new Map([[1, "value1"], ["key2", "value2"]]); // Doesn't compile | |
// The differences between object and Object | |
/* toString(): string; | |
toLocaleString(): string; | |
valueOf(): Object; | |
hasOwnProperty(v: string): boolean; | |
isPrototypeOf(v: Object): boolean; | |
propertyIsEnumerable(v: string): boolean; */ | |
// Object | |
let bigObject: Object; | |
bigObject = 1; | |
bigObject = "1"; | |
bigObject = true; | |
bigObject = Symbol("123"); | |
bigObject = { a: "test" }; | |
bigObject = () => {}; | |
bigObject = [1, 2, 3]; | |
bigObject = new Date(); | |
bigObject = new MyClass(); | |
bigObject = Object.create({}); | |
// object | |
let littleObject: object; | |
littleObject = { a: "test" }; | |
littleObject = new Date(); | |
littleObject = () => {}; | |
littleObject = [1, 2, 3]; | |
littleObject = new MyClass(); | |
littleObject = Object.create({}); | |
// undefined and type null with "strictNullCheck | |
// null & undefined is specials types | |
// neither Object or object | |
let acceptNull: number | null = null; | |
acceptNull = 1; | |
let acceptUndefined: number | undefined = 1; | |
acceptUndefined = null; | |
// Object & object | |
let obj1: Object = {}; | |
let obj2: object = {}; | |
let obj3: {} = {}; | |
let obj4: any = {}; | |
obj1.test = "2"; // Does not compile | |
obj2.test = "2"; // Does not compile | |
obj3.test = "2"; // Does not compile | |
obj4.test = "2"; | |
obj1.toString(); | |
obj2.toString(); | |
obj3.toString(); | |
obj4.toString(); | |
// what is object literal & object literal with type or interface | |
type ObjLiteralType = { x: number; y: number }; | |
interface ObjLiteralType2 { | |
x: number; | |
y: number; | |
} | |
function uppercaseObject(obj: Object): void {} | |
function lowercaseObject(obj: object): void {} | |
function anyObject(obj: any): void {} | |
function objectLiteral(obj: {}): void {} | |
uppercaseObject({ x: 1 }); | |
lowercaseObject({ x: 1 }); | |
anyObject({ x: 1 }); | |
objectLiteral({ x: 1 }); | |
let literalObject: ObjLiteralType = { x: 1, y: 2 }; | |
let literalObject2: ObjLiteralType2 = { x: 1, y: 2 }; | |
/******************************* */ | |
// How to create a constructed object | |
class ClassWithConstructor { | |
constructor() { | |
console.log("Object instantiated"); | |
} | |
} | |
const cwc = new ClassWithConstructor(); | |
function sayHello() {} | |
var obj = new hello(); | |
// explicit type and a cast | |
interface MyObject { | |
a: number; | |
b: string; | |
} | |
const newObject1: MyObject = { a: 1, b: "2" }; | |
const newObject2 = { a: 1, b: "2" } as MyObject; | |
const newObject3 = { a: 1, b: "2", c: "OH NO" } as MyObject; | |
const newObject4 = { a: 1 } as MyObject; | |
// Variable with many types | |
type AcceptedOption = number | string | { option1: string; option2: number }; | |
const myOption1: AcceptedOption = "run"; | |
const myOption2: AcceptedOption = 123; | |
const myOption3: AcceptedOption = { option1: "run", option2: 123 }; | |
function functWithUnion(p: boolean | undefined): undefined | null { | |
return undefined; | |
} | |
interface TypeA { | |
a: string; | |
b: string; | |
} | |
interface TypeB { | |
b: string; | |
c: string; | |
} | |
function functionWithUnion(param1: TypeA | TypeB): void { | |
console.log(param1.b); | |
} | |
// combining types | |
interface TypeA { | |
a: string; | |
b: string; | |
} | |
interface TypeB { | |
b: string; | |
c: string; | |
} | |
type TypeC = TypeA & TypeB; | |
const m: TypeC = { | |
a: "A", | |
b: "B", | |
c: "C" | |
}; | |
interface TypeA { | |
a: string; | |
b: string; | |
} | |
function intersectGeneric<TT1>(t1: TT1): TT1 & TypeA { | |
const x: TypeA = { a: "a", b: "b" }; | |
return (<any>Object).assign({}, x, t1); | |
} | |
const result = intersectGeneric({ c: "c" }); | |
console.log(result); // { a: 'a', b: 'b', c: 'c' } | |
type TypeD3 = (TypeA & TypeB) | (TypeB & TypeA); | |
type TypeD4 = TypeA & TypeB | TypeB & TypeA; | |
type TypeD5 = TypeA & TypeB; | |
// interface intersection | |
interface InterfaceA { | |
m1: string; | |
} | |
interface InterfaceB { | |
m2: string; | |
} | |
type TypeAB = InterfaceA & InterfaceB; | |
interface InterfaceSameField1 { | |
m1: string; | |
} | |
interface InterfaceSameField2 { | |
m1?: string; | |
} | |
type Same = InterfaceSameField1 & InterfaceSameField2; | |
let same: Same = { m1: "This is required" }; | |
// extending interfaces | |
interface InterfaceA { | |
m1: string; | |
} | |
interface InterfaceB { | |
m2: string; | |
} | |
// difference between type & interafces | |
type TPrimitive1 = string; | |
type TPrimitive2 = { m1: string }; | |
// type can't be used to implement | |
class ExtendPrimitiv1 implements TPrimitive1 { | |
// Does not compile | |
} | |
// | |
interface InterfaceMergeAB extends InterfaceA, InterfaceB { | |
m3: string; | |
} | |
//----------------------------------------// | |
// A tuple is an alternative to an object to hold multiple values within a single variable | |
let tuple1 = ["First name", "Last Name", 1980]; // Infered as (string | number)[] | |
tuple1[2] = "Not a number"; | |
let tuple2: [string, string, number] = ["First name", "Last Name", 1980]; // Tuple | |
tuple2[2] = "Not a number"; // Does not compile | |
function restFunction(...args: [number, string, boolean]): void { | |
const p1: number = args[0]; | |
const p2: string = args[1]; | |
const p3: boolean = args[2]; | |
// Code | |
} | |
function resultFunction(p1: number, p2: string, p3: boolean): void { | |
// Code | |
} | |
let tuple4: [number, string, boolean] = [0, "one", false]; | |
let array4: (number | string | boolean)[] = [0, "one", false]; | |
restFunction(...tuple4); | |
restFunction(...array4); // Doesn't compile | |
// declare | |
// The role of declare is to indicate to TypeScript's compiler that the variable exists but is defined somewhere else: | |
declare let myVariable: string; | |
declare module "messageformat" { | |
} | |
// --------------------------------------------------------// | |
// Tranform your code in Classes interfaces | |
//---------------------------------------------------------// | |
/* | |
What is a class and how do we define one? | |
How type comes into play with a class's constructor | |
What is encapsulation using public, private, and protected | |
Reducing the definition of a field with a value set at construction time | |
What is static? | |
Use cases for a non-public constructor | |
Using an object from a class versus an object literal | |
How an interface can be useful in object-oriented | |
Bringing abstraction with an abstract class | |
How to have a property that is read-only | |
Enforcing a specific constructor from an interface | |
*/ | |
export class Variables { | |
public a: number = 1; | |
private b: number = 2; | |
protected c: number = 3; | |
d: number = 4; // Also public | |
} | |
const d = new Variables(); | |
class MyClass { | |
private m1: number; | |
private m2: string; | |
private m3: number; | |
constructor(param1: number, param2: string) { | |
this.m1 = param1; | |
this.m2 = param2; | |
this.m3 = 123; | |
} | |
} | |
class ClassWithConstructorOverloaded { | |
private p1: number; | |
private p2: string; | |
constructor(p1: number); | |
constructor(p1: number, p2?: string) { | |
this.p1 = p1; | |
if (p2 === undefined) { | |
p2 = "default"; | |
} | |
this.p2 = p2; | |
} | |
} | |
export class Variables1 { | |
private b: number = 2; | |
} | |
const d = new Variables1(); | |
d.b = 100; // Not allowed, won’t compile | |
console.log(d.b); // Not allowed, won’t compile | |
// private & protected | |
class BaseClass { | |
public a: number = 1; | |
private b: number = 2; | |
protected c: number = 3; | |
} | |
class ChildClass extends BaseClass { | |
public d: number = 1; | |
private e: number = 2; | |
protected f: number = 3; | |
public f1(): void { | |
super.a; | |
super.c; | |
this.a; | |
this.c; | |
} | |
} | |
const child = new ChildClass(); | |
console.log(child.a); | |
console.log(child.d); | |
// abstract class | |
abstract class FakeStaticClass { | |
public static m1: number; | |
public static f1(): void {} | |
} | |
console.log(FakeStaticClass.m1); | |
FakeStaticClass.f1(); | |
const instance1 = new FakeStaticClass(); // Doesn't compile | |
// static members | |
class StaticClass { | |
public static ps: number; | |
private static privateStatic: number; | |
protected static protecStatic: number; | |
} | |
StaticClass.ps = 1; | |
// private constructor | |
class PrivateConstructor { | |
private constructor() {} | |
} | |
const pc = new PrivateConstructor(); // Does not compile | |
// singleton using private constructor | |
class SingletonClass { | |
private static instance: SingletonClass; | |
private constructor() { | |
SingletonClass.instance = new SingletonClass(); | |
} | |
public static GetInstance(): SingletonClass { | |
return SingletonClass.instance; | |
} | |
} | |
const singletonClass = SingletonClass.GetInstance(); | |
// private function in a class | |
// interface for OOPS | |
class ClassA { | |
public mainFunction(): void { | |
this.subFunction1(); | |
this.subFunction2(); | |
} | |
private subFunction1(): void {} | |
private subFunction2(): void {} | |
} | |
interface IClassA { | |
mainFunction(): void; | |
} | |
class ClassA2 implements IClassA { | |
public mainFunction(): void { | |
this.subFunction1(); | |
this.subFunction2(); | |
} | |
public subFunction1(): void {} | |
public subFunction2(): void {} | |
} | |
// abstraction of functions | |
abstract class MainClass { | |
public mainCoreLogic(): void { | |
// Code here [A] | |
this.delegatedLogic(); | |
// Code here [B] | |
} | |
public abstract delegatedLogic(): void; | |
} | |
class CustomLogic extends MainClass { | |
public delegatedLogic(): void { | |
// Do some custom logic here [C] | |
} | |
} | |
// readonly property in Interfce or classes | |
interface I1 { | |
readonly id: string; | |
name: string; | |
} | |
let i1: I1 = { | |
id: "1", | |
name: "test" | |
}; | |
i1.id = "123"; // Does not compile | |
class C1 { | |
public readonly id: string = "C1"; | |
constructor() { | |
this.id = "Still can change"; | |
} | |
public f1(): void { | |
this.id = 1; // Doesn't compile | |
} | |
} | |
//*************************************** */ | |
/* | |
How to check with a guarantee for undefined and null | |
Do I need to check every possibility of a union to have the right type? | |
What is the limitation of instanceof? | |
Why a discriminator is essential for type identification | |
Why using user defined guard | |
How and why to cast | |
What is a type assertion? | |
How to compare classes | |
*/ | |
//*********************************************** */ | |
// typeof | |
const a = "test"; | |
let b: number = 2; | |
const c: boolean = true; | |
let d: number | string = "test"; | |
console.log(typeof a); // string | |
console.log(typeof b); // number | |
console.log(typeof c); // boolean | |
console.log(typeof d); // string | |
let g: number | undefined = undefined; | |
let h: number | undefined | null = null; | |
console.log(typeof g); | |
console.log(typeof h); | |
// null & undefined | |
let g: number | undefined = undefined; | |
let h: number | undefined | null = null; | |
console.log(typeof g); // undefined | |
console.log(typeof h); // object | |
console.log(g === undefined); // true | |
console.log(g === null); // false | |
// getting type for union Types | |
function myFunction(value: number | undefined): void { | |
console.log("Value is number or undefined"); | |
if (value === undefined) { | |
console.log("Value is undefined"); | |
} else { | |
console.log("Value is NOT undefined, hence a number"); | |
} | |
console.log("Value is number or undefined"); | |
} | |
// instanceof | |
class MyClass1 { | |
member1: string = "default"; | |
member2: number = 123; | |
} | |
class MyClass2 { | |
member1: string = "default"; | |
member2: number = 123; | |
} | |
const a = new MyClass1(); | |
const b = new MyClass2(); | |
if (a instanceof MyClass1) { | |
console.log("a === MyClass1"); | |
} | |
if (b instanceof MyClass2) { | |
console.log("b === MyClass2"); | |
} | |
//********************************** */ | |
/* | |
How generic can make your code reusable | |
Accepted kinds of data structure for generic type | |
How to constrain the generic type | |
Generic and intersection | |
Default generic | |
Generic optional type | |
Generic constraints with a union type | |
Restricting string choices with keyof | |
Limiting the access to members of a generic type | |
*/ | |
/************************************************ */ | |
/// generics with Interfaces | |
interface MyCustomTypeA { | |
test: string; | |
} | |
interface MyCustomTypeB { | |
anything: boolean; | |
} | |
interface ReusableInterface3<T> { | |
entity: T; | |
} | |
const ri3a: ReusableInterface3<MyCustomTypeA> = { entity: { test: "yes" } }; | |
const ri3b: ReusableInterface3<MyCustomTypeB> = { entity: { anything: true } }; | |
const ri3c: ReusableInterface3<number> = { entity: 1 }; | |
// accepted types for genrics | |
type MyTypeA<T> = T | string; // Type | |
interface MyInterface<TField, YField> { | |
// Interface wiht two types | |
entity1: TField; | |
myFunction(): YField; | |
} | |
class MyClass4<T> { | |
// Class | |
list: T[] = []; | |
public displayFirst(): void { | |
const first: T = this.list[0]; // Variable | |
console.log(first); | |
} | |
} | |
// read it | |
function extractFirstElement<T, R>(list: T[], param2: R): T { | |
console.log(param2); | |
return list[0]; | |
} | |
// extending genrics types | |
interface AnyKindOfObject { | |
what: string; | |
} | |
interface ReusableInterface3<T extends object> { | |
entity: T; | |
} | |
const d: ReusableInterface3<AnyKindOfObject> = { entity: a }; | |
console.log(d.entity.what); // Compile | |
// extends | |
interface ObjectWithId { | |
id: number; | |
what: string; | |
} | |
interface ReusableInterface4<T extends { id: number }> { | |
entity: T; | |
} | |
const e: ReusableInterface4<AnyKindOfObject> = { entity: { id: 5, what: 1 } }; // Doesn't compile | |
const f: ReusableInterface4<ObjectWithId> = { entity: { id: 1, what: "1" } }; // Compile | |
const g: ReusableInterface4<string> = { entity: "test" }; // Doesn't compile | |
// generics | |
interface WithId { | |
id: number; | |
} | |
interface User { | |
name: string; | |
} | |
interface Developer extends User { | |
favoriteLanguage: string; | |
} | |
function identifyUser<T extends User>(user: T): T & WithId { | |
const newUser = (<any>Object).assign({}, user, { id: 1 }); | |
return newUser; | |
} | |
const user: Developer = { name: "Patrick", favoriteLanguage: "TypeScript" }; | |
const userWithId = identifyUser(user); | |
function merge<T, U>(obj1: T, obj2: U): T & U { | |
return Object.assign({}, obj1, obj2); | |
} | |
// optional generics | |
function shows<T>(p1?: T): void { | |
console.log(p1); | |
} | |
shows(); // p1 is {} | undefined | |
shows("123"); | |
shows(123); | |
// generics with union type | |
interface ObjectWithAge { | |
kind: "ObjectWithAge"; | |
age: number; | |
} | |
function funct8<T extends ObjectWithAge | ObjectWithAge[]>(p: T): T { | |
if (p instanceof Array) { | |
return p[0]; | |
} | |
return p; | |
} | |
// keysof belo example why it will fail\ | |
interface Human { | |
name: string; | |
birthdate: Date; | |
isHappy: boolean; | |
} | |
const me: Human = { | |
name: "Patrick", | |
birthdate: new Date(1912, 0, 1), | |
isHappy: true | |
}; | |
function showMe1(obj: Human, field: string): void { | |
console.log(obj[field]); // Does not compile | |
} | |
showMe1(me, "demmo"); | |
function showMe2(obj: Human, field: keyof Human): void { | |
console.log(obj[field]); | |
} | |
showMe2(me, "NOname"); // Does not compile | |
//********************************************************* */ | |
/* | |
How to use a third-party library definition file | |
How TypeScript can generate a definition file | |
How to manually add a definition file for a JavaScript project | |
How to merge types into an existing definition file | |
How to create a definition file for a JavaScript project*/ | |
//********************************************************** */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment