(FRONT) FRONT (2022)

( << Back) Type.ts

   1:  console.log(`
   2:  --- 1 --- enum definition
   3:  `)
   4:  enum Color { red, blue };
   5:   
   6:  console.log(`
   7:  --- 2 --- TS types: literal, enum, js bigint, arrow function type, tuple, reference to function, online function reference definition, readonly, three more types see later
   8:  `)
   9:  //An object in JavaScript is a key/value map, type is describe it
  10:  type T = {
  11:      sarr: string[],
  12:      lit: 'a' | 'b',          // literal type
  13:      c: Color,                // enum type
  14:      num: bigint,             // js bigint
  15:      opt?: Date,              // Ts Date is not the same as JS date, question mark is optional property
  16:      arr: (x: Date) => Date,  // arrow function type
  17:      tupl: [number, string],  // tuple, Tuple Types, A tuple type is another sort of Array type that knows exactly how many elements it contains, and exactly which types it contains at specific positions.
  18:      ref: Function,           // reference to function
  19:      f(z: number[]): void,    // ref to function
  20:      readonly body: string,   // readonly type, it won’t change any behavior at runtime
  21:      // tree more type - anonomus signature, callable, newable mention below
  22:  }
  23:   
  24:  console.log(`
  25:  --- 3 --- implements types: private props, constructor
  26:  `)
  27:   
  28:  class A implements T {
  29:      #private: Function;
  30:      constructor(x: Function) { this.#private = x };
  31:      opt?: Date;
  32:      static opt?: Date;
  33:      sarr: string[] = ['1'];
  34:      lit: 'a' | 'b' = "b";
  35:      c!: Color;
  36:      num!: bigint;
  37:      tupl!: [number, string];
  38:      ref!: Function;
  39:      f(z: number[]): void {
  40:          A.opt = new Date(z[0], z[1], z[2])
  41:      };
  42:      body!: '';
  43:      arr!: (x: Date) => Date;
  44:  }
  45:   
  46:  console.log(`
  47:  --- 4 --- create class instance, use TS BigInt, set reference to function
  48:  `)
  49:   
  50:  const B = new A(() => 1)
  51:   
  52:  B.f = (_el: any): number => { return 1 } //_mean variable not need
  53:  B.c = Color.blue
  54:  B.tupl = [1, 'w']
  55:  B.num = BigInt(true)
  56:   
  57:  console.log(`
  58:  --- 5 --- two way object dumping (JSON.stringify + Object.Keys) and replacer function to serialise bigint
  59:  `)
  60:   
  61:  console.log(JSON.stringify(B, (_: any, v: any) => typeof v === 'bigint' ? v.toString() : v))
  62:   
  63:  console.log(`
  64:  --- 6 --- keyof T as type for computed property type definition, Object.keys().ForEach(()=>{})
  65:  `)
  66:   
  67:  Object.keys(B).forEach((v, i) => console.log(i, v, B[v as keyof T]))
  68:   
  69:  console.log(`
  70:  --- 7 --- hack using KeyOf with Index Signatures with type Any
  71:  `)
  72:   
  73:  type hack = { [key: string]: any; } & T
  74:  const H: hack = B
  75:  Object.keys(H).forEach((v, i) => console.log(i, v, H[v]))
  76:   
  77:  console.log(`
  78:  --- 8 --- using Map and String,Join to colect all object keys
  79:  `)
  80:   
  81:  let values = Object.keys(H).map((v, i) => H[v])
  82:  console.log(values.join(";"))
  83:   
  84:  console.log(`
  85:  --- 9 --- Object.values() is part of ES2017
  86:  `)
  87:   
  88:  Object.values(H).forEach((v, i) => console.log(i, Object.keys(H)[i], v))
  89:   
  90:  console.log(`
  91:  --- 10 --- assembly array of object properties with Map abd using TypeOf and KeyOf, Type Capturing when object type is unknown
  92:  `)
  93:   
  94:  type T1 = typeof B;
  95:  const PropArr1: Array<Object> = Object.keys(B).map((v, i) => {
  96:      return { key: v, value: B[v as keyof T1] }
  97:  });
  98:   
  99:  PropArr1.forEach((x, i) => console.log(i, x))
 100:   
 101:  console.log(`
 102:  --- 11 --- indexed property, this type accept any string as key and any number as value
 103:  `)
 104:   
 105:  type T2 = {
 106:      [key: string]: number
 107:  }
 108:  const Obj: T2 = { 'a': 1, 'b': 2 }
 109:  console.log(Obj)
 110:   
 111:  console.log(`
 112:  --- 12 --- define type with anonymous function signature, at common type is the same as interface
 113:  `)
 114:   
 115:  type Func1 = {
 116:      (x: string, y: string): boolean;
 117:  }
 118:   
 119:  interface Func2 {
 120:      (a: number, b: number): bigint;
 121:  }
 122:   
 123:  let search: Func1;
 124:  let mult: Func2;
 125:   
 126:  search = function (src, sub) {
 127:      let result = src.search(sub);
 128:      return result > -1;
 129:  };
 130:   
 131:  mult = (one, two) => BigInt(one * two)
 132:   
 133:  console.log(search('abc', 'a'), mult(20, 30))
 134:   
 135:  console.log(`
 136:  --- 13 --- combine two two types with &, Error object, BigInt literals are not available when targeting lower than ES2020
 137:  `)
 138:   
 139:  //combine two interface
 140:  type Func3 = { m: Error } & T
 141:  let f3: Func3 = {
 142:      m: new Error,
 143:      sarr: ['1'],
 144:      lit: "b",
 145:      c: Color.blue,
 146:      num: 1n,             //BigInt literals are not available when targeting lower than ES2020
 147:      tupl: [5, 's'],
 148:      ref: Function,
 149:      f(z: number[]): void {
 150:          A.opt = new Date(z[0], z[1], z[2])
 151:      },
 152:      body: '',
 153:      arr: (x: Date) => new Date(x)
 154:  }
 155:  console.log(f3)
 156:   
 157:  console.log(`
 158:  --- 14 --- callable type mean inteface of arrow function, overloading interface, declare mean external declaration
 159:  `)
 160:   
 161:  // callable type + overloading interface + external declaration
 162:  type callableType = {
 163:      (foo: string, bar?: number, ...others: boolean[]): number;
 164:      (foo: number, bar?: number, ...others: boolean[]): number; //Overloaded interface
 165:  }
 166:   
 167:  const foo1 = (x: string) => 1
 168:  const foo2 = (x: number) => 2
 169:  const bar1 = foo1('');            //bar is inferred as a string
 170:  const bar2 = foo2(1);             //bar is inferred as a number
 171:   
 172:  console.log(bar1, bar2)
 173:   
 174:  console.log(`
 175:  --- 15 --- newable type mean inteface require new instance
 176:  `)
 177:   
 178:  // newable type - require new
 179:  type newableType = {
 180:      new(foo: string, bar?: number, ...others: boolean[]): number;
 181:  }
 182:  declare const fo: newableType; //declare mean that variable exists already, and therefore can be referenced by external code
 183:   
 184:  const bar3 = new Function("")
 185:  console.log(bar3)
 186:   
 187:   
 188:  console.log(`
 189:  --- 16 --- If you want to enforce only certain newables, you can specify the constructor's return type
 190:  `)
 191:   
 192:  interface Newable {
 193:      errorConstructor: new (...args: any) => Error; // <- put here whatever Base Class you want
 194:  }
 195:   
 196:  class NotError { }
 197:  class MyError extends Error { }
 198:  /*
 199:  const errorCreator1: Newable = {
 200:      errorConstructor: NotError, // Type 'typeof NotError' is missing the following properties from type 'typeof AnyError': captureStackTrace, stackTraceLimitts
 201:  };
 202:  */
 203:  const errorCreator2: Newable = {
 204:      errorConstructor: MyError, // OK
 205:  };
 206:   
 207:  console.log(errorCreator2)
 208:   
 209:  console.log(`
 210:  --- 17 --- with infer keyword the compiler ensures that you have declared all type variables explicitly https://stackoverflow.com/questions/60067100/why-is-the-infer-keyword-needed-in-typescript
 211:  `)
 212:   
 213:  type MyT<T> = T extends infer R ? R : never;
 214:  type Tx = MyT<{ b: string }> // T1 is { b: string; }
 215:   
 216:  //infer R shadows type references of an equally-named type declaration R:
 217:   
 218:  type R = { a: number }
 219:  type MyType4<T> = T extends infer R ? R : never;
 220:  type T4 = MyType4<{ b: string }> // { b: string; }
 221:   
 222:   
 223:  console.log(`
 224:  --- 18 --- You can't define a static property on an interface in TypeScript. Because Date is an interface in TypeScript, you can't extend it with a class using the extends keyword, but can provide a MinValue property on the prototype. Static properties are usually placed on the (global) constructor for the object, whereas the "interface" keyword applies to instances of the object.
 225:  `)
 226:   
 227:  class RichDate {
 228:      public static MinValue = new Date();
 229:  }
 230:  interface Date {
 231:      MinValue: Date;
 232:  }
 233:   
 234:  Date.prototype.MinValue = new Date(0);
 235:   
 236:  var x = new Date();
 237:  console.log(x.MinValue);
 238:   
 239:  console.log(`
 240:  --- 19 --- Type Inference, When a type inference is made from several expressions, the types of those expressions are used to calculate a “best common type”
 241:  `)
 242:   
 243:  let var3 = [0, 1, null];
 244:  type T3 = typeof var3
 245:   
 246:  console.log(`
 247:  --- 20 --- Type Aliases. Type Aliases can be used for primitives like string or more complex types such as objects and arrays:
 248:  `)
 249:  type CarYear = number
 250:  type CarType = string
 251:  type CarModel = string
 252:  type Car = {
 253:      year: CarYear,
 254:      type: CarType,
 255:      model: CarModel
 256:  }
 257:  const carYear: CarYear = 2001
 258:  const carType: CarType = "Toyota"
 259:  const carModel: CarModel = "Corolla"
 260:  const car: Car = {
 261:      year: carYear,
 262:      type: carType,
 263:      model: carModel
 264:  };
 265:   
 266:  console.log(`
 267:  --- 21 --- Interfaces are similar to type aliases, except they only apply to object types. Interfaces can extend each other's definition.
 268:  `)
 269:   
 270:  interface Rectangle {
 271:      height: number,
 272:      width: number
 273:  }
 274:   
 275:  const rectangle: Rectangle = {
 276:      height: 20,
 277:      width: 10
 278:  };
 279:   
 280:  console.log(`
 281:  --- 22 --- TypeScript has special types that may not refer to any specific type of data. any/unknown/never/undefined & null https://www.w3schools.com/typescript/typescript_special_types.php
 282:  `)
 283:   
 284:  // 1. any
 285:   
 286:  let v: any = true;
 287:  v = "string";
 288:  Math.round(v);
 289:   
 290:  // 2. unknown is a similar, but safer alternative to any
 291:   
 292:  let w: unknown = 1;
 293:  w = "string"; // no error
 294:  w = {
 295:      runANonExistentMethod: () => {
 296:          console.log("I think therefore I am");
 297:      }
 298:  } as { runANonExistentMethod: () => void }
 299:  // How can we avoid the error for the code commented out below when we don't know the type?
 300:  // w.runANonExistentMethod(); // Error: Object is of type 'unknown'.
 301:  if (typeof w === 'object' && w !== null) {
 302:      (w as { runANonExistentMethod: Function }).runANonExistentMethod();
 303:  }
 304:  // Although we have to cast multiple times we can do a check in the if to secure our type and have a safer casting 
 305:   
 306:  // 3. never effectively throws an error whenever it is defined.
 307:  let uu: never
 308:   
 309:  // 4. undefined and null are types that refer to the JavaScript primitives undefined and null respectively
 310:   
 311:  let u1: undefined = undefined;
 312:  let u2: null = null;
 313:   
 314:  console.log(`
 315:  --- 23 --- async function Promise
 316:  `)
 317:   
 318:  let gt = async function getFavoriteNumber(): Promise<number> {
 319:      return 26;
 320:  }
 321:   
 322:  let tt = typeof gt
 323:   
 324:  console.log(`
 325:  --- 24 --- type assetions 
 326:  `)
 327:   
 328:  const myCanvas1 = document.getElementById("main_canvas") as HTMLCanvasElement;
 329:  const myCanvas2 = <HTMLCanvasElement>document.getElementById("main_canvas");
 330:   
 331:  console.log(`
 332:  --- 25 --- Literal Types, In addition to the general types string and number, we can refer to specific strings and numbers in type positions.
 333:  `)
 334:   
 335:  function compare(a: string, b: string): -1 | 0 | 1 {
 336:      return a === b ? 0 : a > b ? 1 : -1;
 337:  }





Comments ( )
Link to this page: http://www.vb-net.com/TypescriptLearningStartPoint/Type.htm
< THANKS ME>