(FRONT) FRONT (2022)

( << Back) TypeVsInterface.ts

   1:  console.log(`
   2:  --- 1 --- interface vs type
   3:  `)
   4:   
   5:  //interface vs types (2018)
   6:  //https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript/52682220#52682220
   7:  //
   8:  //Type  Interface 
   9:  //✅    ✅      Can describe functions     
  10:  //✅    ✅      Can describe constructors     
  11:  //✅    ✅      Can describe tuples     
  12:  //✅    ✅      Can be mapped over with mapped types     
  13:  //✅    ⚠️      Can intersect another one of its kind     
  14:  //✅    🚫      Can create a union with another one of its kind     
  15:  //✅    🚫      Can be used to create mapped types     
  16:  //✅    🚫      Expands in error messages and logs     
  17:  //⚠️     ✅      Classes can implement it (implements)     
  18:  //⚠️     ✅      Can be recursive     
  19:  //⚠️     ✅      Interfaces can extend it     
  20:  //🚫     ✅      Classes can extend it     
  21:  //🚫     ✅      Can be augmented     
  22:  //
  23:  //for 2021 version (summary)
  24:  //
  25:  //When to use type:
  26:  //
  27:  //    Use type when defining an alias for primitive types (string, boolean, number, bigint, symbol, etc)
  28:  //    Use type when defining tuple types
  29:  //    Use type when defining function types
  30:  //    Use type when defining a union
  31:  //    Use type when trying to overload functions in object types via composition
  32:  //    Use type when needing to take advantage of mapped types
  33:  //
  34:  //When to use interface:
  35:  //
  36:  //    Use interface for all object types where using type is not required (see above)
  37:  //    Use interface when you want to take advantage of declaration merging.
  38:   
  39:   
  40:  //Only type can be used to alias a primitive:
  41:  type Primitive = number | string | boolean | null | undefined
  42:  type Nullish = null | undefined;
  43:  type Fruit = 'apple' | 'pear' | 'orange';
  44:  type Num = number | bigint;
  45:   
  46:  //Tuples can only be typed via the type keyword:
  47:  type row = [colOne: number, colTwo: string];
  48:   
  49:  //Functions can be typed by both the type and interface keywords:
  50:  interface Point1 {
  51:      x: number;
  52:      y: number;
  53:  }
  54:   
  55:  interface SetPoint1 {
  56:      (x: number, y: number): void;
  57:  }
  58:   
  59:  type Point2 = {
  60:      x: number;
  61:      y: number;
  62:  };
  63:   
  64:  type SetPoint2 = (x: number, y: number) => void;
  65:   
  66:  //Union types can only be achieved with the type keyword:
  67:  type Vegetable = 'broccoli' | 'carrot' | 'lettuce';
  68:  type HealthyFoods = Fruit | Vegetable;
  69:   
  70:  //types and inerface composition vith the same JS key/value , declaration can Merging (see above example of hacking keyof)
  71:   
  72:  interface NumLogger {
  73:      log: (val: number) => void;
  74:  }
  75:  type StrAndNumLogger1 = NumLogger & {
  76:      log: (val: string) => void;
  77:  }
  78:   
  79:  const logger: StrAndNumLogger1 = {
  80:      log: (val: string | number) => console.log(val)
  81:  }
  82:   
  83:  logger.log(1)
  84:  logger.log('hi')
  85:   
  86:  console.log(`
  87:  --- 2 --- Use the type when you are transforming multiple types into a single generic type. Nullable<T> ,  NonNull<T>, Never type and ternary operator with types
  88:  `)
  89:   
  90:  //Generic Transformations. Use the type when you are transforming multiple types into a single generic type.
  91:  type Nullable<T> = T | null | undefined
  92:  type NonNull<T> = T extends (null | undefined) ? never : T
  93:   
  94:  console.log(`
  95:  --- 3 --- Mapped object types possible obly with Type
  96:  `)
  97:   
  98:  type FruitCount = {
  99:      [key in Fruit]: number;
 100:  }
 101:   
 102:  const fruits: FruitCount = {
 103:      apple: 2,
 104:      orange: 3,
 105:      pear: 0
 106:  };
 107:   
 108:  console.log(fruits)
 109:   
 110:  console.log(`
 111:  --- 4 --- The key difference pointed out in the documentation is that Interface can be reopened to add new property but Type alias cannot be reopened to add new property 
 112:  `)
 113:   
 114:  interface I1 {
 115:      name: string
 116:  }
 117:   
 118:  interface I1 {
 119:      age: number
 120:  }
 121:   
 122:  let var1: I1 = { name: 'a', age: 10 }
 123:  console.log(var1)
 124:   
 125:  console.log(`
 126:  --- 5 --- Difference types and intefaces in indexing.  https://stackoverflow.com/questions/37233735/interfaces-vs-types-in-typescript
 127:  `)
 128:   
 129:  interface MyInterface {
 130:      foobar: string;
 131:  }
 132:   
 133:  type MyType = {
 134:      foobar: string;
 135:  }
 136:   
 137:  const exampleInterface: MyInterface = { foobar: 'hello world' };
 138:  const exampleType: MyType = { foobar: 'hello world' };
 139:   
 140:  //Construct a type with a set of properties K of type T
 141:  //type Record<K extends string | number | symbol, T> = { [P in K]: T; }
 142:  let record: Record<string, string> = {};
 143:   
 144:  record = exampleType;      // Compiles
 145:  //record = exampleInterface; // Index signature is missing
 146:   
 147:  console.log(`
 148:  --- 6 --- Index signature is missing in type (only on interfaces, not on type alias)  https://github.com/microsoft/TypeScript/issues/15300
 149:  `)
 150:   
 151:  interface IndexType {
 152:      [key: string]: string;
 153:  }
 154:   
 155:  interface doesNotWork {
 156:      hola: string;
 157:  }
 158:  type doWorks = { hola: string };
 159:   
 160:  let y: IndexType;
 161:   
 162:  const correctA = { hola: "hello" };
 163:  const correctB: doWorks = { hola: "hello" };
 164:   
 165:  //error should be assignable to y
 166:  const error: doesNotWork = { hola: "hello " };
 167:   
 168:  y = correctA;
 169:  y = correctB;
 170:  /**
 171:  /* y = error; //Index signature is missing in type 'doesNotWork'
 172:  */
 173:  y = { ...error }; //workaround but not equivalent since the instance is not the same
 174:  console.log(y, correctA, correctB, error)
 175:   
 176:  console.log(`
 177:  --- 7 --- Difference in evaluation 
 178:  `)
 179:   
 180:  /**
 181:   * When FirstLevelType is interface 
 182:   */
 183:   
 184:  interface FirstLevelType1<A, Z> {
 185:      _: "typeCheck";
 186:  };
 187:   
 188:  type TestWrapperType1<T, U> = FirstLevelType1<T, U>;
 189:   
 190:   
 191:  const a1: TestWrapperType1<{ cat: string }, { dog: number }> = {
 192:      _: "typeCheck",
 193:  };
 194:   
 195:  // {  cat: string; }
 196:  type ExtendFirst1 = typeof a1 extends FirstLevelType1<infer T, infer _>
 197:      ? T
 198:      : "not extended";
 199:   
 200:  const a11: ExtendFirst1 = { cat: '' }
 201:   
 202:  console.log(a1, a11)
 203:   
 204:  /**
 205:   * When FirstLevelType is type
 206:   */
 207:  type FirstLevelType2<A, Z> = {
 208:      _: "typeCheck";
 209:  };
 210:   
 211:  type TestWrapperType2<T, U> = FirstLevelType2<T, U>;
 212:   
 213:   
 214:  const a2: TestWrapperType2<{ cat: string }, { dog: number }> = {
 215:      _: "typeCheck",
 216:  };
 217:   
 218:  // unknown
 219:  type ExtendFirst2 = typeof a2 extends FirstLevelType2<infer T, infer _>
 220:      ? T
 221:      : "not extended";
 222:   
 223:  const a21: ExtendFirst2 = { cat: '' }
 224:   
 225:  console.log(a2, a21)





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