(AngularTypesctiptLearning) AngularTypesctiptLearning (2022)

Javascript-Typescript difference

Type system:

1. Type Annotations

   1:  
   2:  class Person {
   3:    name: string;
   4:    age: number;
   5:    
   6:    constructor(name: string, age: number) {
   7:      this.name = name;
   8:      this.age = age;
   9:    }
  10:  }
  11:    

   1:  
   2:  class Person {
   3:    constructor(name, age) {
   4:      this.name = name;
   5:      this.age = age;
   6:    }
   7:  }
   8:    

2. Type Coercion, strict type checking

   1:  
   2:  class Example {
   3:    value: number;
   4:    
   5:    constructor(value: number) {
   6:      this.value = value + "5"; // Error: can't concatenate number with string
   7:    }
   8:  }
   9:    

   1:  
   2:  class Example {
   3:    constructor(value) {
   4:      this.value = value + "5"; // type coercion: "55" if value is 5
   5:    }
   6:  }
   7:    

3. Compiler time Type Narrowing (TS-Only)

   1:  
   2:  function printLength(obj: string | string[]) {
   3:    if (typeof obj === "string") {
   4:      console.log(obj.length); // TS knows obj is string here
   5:    } else {
   6:      console.log(obj.length); // TS knows obj is array here
   7:    }
   8:  }
   9:    

   1:  
   2:  function printLength(obj) {
   3:    // No automatic type narrowing
   4:    if (typeof obj === "string") {
   5:      console.log(obj.length);
   6:    } else {
   7:      // ❌ Risky: obj could be anything
   8:      console.log(obj.length); 
   9:    }
  10:  }
  11:    

4. JSON Parsing with type assertion

   1:  
   2:  const data = JSON.parse('{"name":"Alice"}') as { name: string };
   3:  console.log(data.age); // Property 'age' does not exist
   4:    

5. Type Imports (TS only)

   1:  
   2:  // types.ts
   3:  export type User = { name: string; age: number };
   4:  
   5:  // app.ts
   6:  import type { User } from './types'; // Only imports the type (erased at runtime)
   7:  
   8:  const user: User = { name: "Alice", age: 30 }; // Type usage
   9:    

6. Type-safe dynamic import (TS only)

   1:  
   2:  const module = await import('./module') as typeof import('./module');
   3:    

   1:  
   2:  const module = await import('./module'); // Anything goes
   3:    

7. User-Defined Type Guards

   1:  
   2:  function isCat(animal: Animal): animal is Cat {
   3:    return animal.type === "cat";
   4:  }
   5:  if (isCat(animal)) {
   6:    animal.meow(); // TS knows animal is Cat here
   7:  }
   8:    

   1:  
   2:  function isCat(animal) {
   3:    return animal.type === "cat";
   4:  }
   5:  if (isCat(animal)) {
   6:    animal.meow(); // No guarantee has meow() method
   7:  }
   8:    

8. Define API Response type

   1:  
   2:  interface User { id: number; name: string }
   3:  fetch('/user').then(res => res.json() as Promise<User>);
   4:    

   1:  
   2:  fetch('/user').then(res => res.json()); // Could be anything
   3:    

Array:

9. Tuple Types (TS-Only)

   1:  
   2:  let coordinates: [number, number] = [10, 20];
   3:  coordinates = [30, 40]; // 
   4:  coordinates = [10, "20"]; // Error: string not assignable to number
   5:  coordinates = [10]; // Error: 
   6:    

   1:  
   2:  let coordinates = [10, 20];
   3:  coordinates = [30, 40]; /
   4:  coordinates = [10, "20"]; // JS allows mixed types
   5:    

10. Compiler time Array Methods checking (TS-Only)

   1:  
   2:  const numbers = [1, 2, 3];
   3:  numbers.map(num => num.toUpperCase()); // toUpperCase doesn't exist on numbers
   4:    

   1:  
   2:  const numbers = [1, 2, 3];
   3:  numbers.map(num => num.toUpperCase()); // runtime error
   4:    

11. Array Type Safety (TS only)

   1:  
   2:  const ids: number[] = [1, 2, 3];
   3:  ids.push("4"); //  Error
   4:    

   1:  
   2:  const ids = [1, 2, 3];
   3:  ids.push("4"); // JavaScriptЖ (mixed-type array)
   4:    

12. Immutable Readonly Arrays (TS only)

   1:  
   2:  const nums: readonly number[] = [1, 2, 3];
   3:  nums.push(4); //  push doesn't exist on readonly array
   4:    

   1:  
   2:  // JavaScript array always mutable
   3:  const nums = [1, 2, 3];
   4:  nums.push(4); //  Works
   5:    

Function:

13. Function Typing (TS only)

   1:  
   2:  function greet(name: string): string {
   3:    return `Hello, ${name}!`;
   4:  }
   5:    

14. Function Overloads (TS only)

   1:  
   2:  function pad(value: string, padding: number): string;
   3:  function pad(value: number, padding: string): number;
   4:  function pad(value: any, padding: any) { ... }
   5:    

   1:  
   2:  function pad(value, padding) { ... }
   3:    

Enums:

15. Enums (TS only)

   1:  
   2:  enum Status {
   3:    Active = 'ACTIVE',
   4:    Inactive = 'INACTIVE'
   5:  }
   6:    

   1:  
   2:  const Status = {
   3:    Active: 'ACTIVE',
   4:    Inactive: 'INACTIVE'
   5:  };
   6:    

16. Enum Reverse Mapping (TS only)

   1:  
   2:  // TypeScript (bi-directional enums)
   3:  enum Color { Red = 1 }
   4:  console.log(Color[1]); // ✅ "Red"
   5:    

   1:  
   2:  const Color = { Red: 1 };
   3:  console.log(Color[1]); // ❌ undefined (no auto-mapping)
   4:    

This:

17. Explicit this binding vs dynamic this

   1:  
   2:  function onClick(this: HTMLButtonElement) {
   3:    console.log(this.textContent);
   4:  }
   5:    

   1:  
   2:  function onClick() {
   3:    console.log(this.textContent); // Risky context
   4:  }
   5:    

Property:

18. Access Modifiers

   1:  
   2:  class Person {
   3:    public name: string;    // accessible anywhere (default)
   4:    private age: number;    // only accessible within class
   5:    protected id: string;   // accessible within class and subclasses
   6:    readonly birthDate: Date; // can't be modified after initialization
   7:  }
   8:    

   1:  
   2:  class Person {
   3:    #age;  // private field 
   4:    
   5:    constructor(age) {
   6:      this.#age = age;
   7:    }
   8:  }
   9:    

19. Parameter Properties (TS only)

   1:  
   2:  class Person {
   3:    constructor(public name: string, private age: number) {
   4:      // automatically creates and assigns this.name and this.age
   5:    }
   6:  }
   7:    

20. Method Overloading (TS only)

   1:  
   2:  class Logger {
   3:    log(message: string): void;
   4:    log(message: string, level: number): void;
   5:    log(message: any, level?: any): void {
   6:      // Implementation
   7:    }
   8:  }
   9:    

   1:  
   2:  class Logger {
   3:    log(message, level) {
   4:      // no overloading, just multiple parameters
   5:    }
   6:  }
   7:    

21. Property Initialization (TS only)

   1:  
   2:  class Person {
   3:    name: string; // Error if strictPropertyInitialization is enabled
   4:    
   5:    constructor() {
   6:      this.name = "Default"; // Required initialization
   7:    }
   8:  }
   9:    

22. Property Declaration

   1:  
   2:  class Example {
   3:    prop: string; // Must declare first, requires explicit declaration
   4:    constructor() {
   5:      this.prop = "value";
   6:    }
   7:  }
   8:    

   1:  
   2:  class Example {
   3:    constructor() {
   4:      this.prop = "value"; // No declaration needed, property can add properties dynamically
   5:    }
   6:  }
   7:    

23. Autodeclaration variable in constructor

   1:  
   2:  class Point {
   3:    constructor(public x: number, public y: number) {}
   4:    // Auto-declares and assigns this.x and this.y
   5:  }
   6:    

   1:  
   2:  class Point {
   3:    constructor(x, y) {    // must declare explicitly
   4:      this.x = x;
   5:      this.y = y;
   6:    }
   7:  }
   8:    

24. Property Accessors (Getters/Setters)

   1:  
   2:  class Person {
   3:    private _age: number;
   4:  
   5:    get age(): number {
   6:      return this._age;
   7:    }
   8:  
   9:    set age(value: number) {
  10:      if (value < 0) throw new Error("Age cannot be negative");
  11:      this._age = value;
  12:    }
  13:  }
  14:    

   1:  
   2:  class Person {
   3:    #age; // Private field
   4:  
   5:    get age() {
   6:      return this.#age;
   7:    }
   8:  
   9:    set age(value) {
  10:      if (value < 0) throw new Error("Age cannot be negative");
  11:      this.#age = value;
  12:    }
  13:  }
  14:    

25. Static Properties

   1:  
   2:  class MyClass {
   3:    static count: number = 0;
   4:    static increment(): void {
   5:      MyClass.count++;
   6:    }
   7:  }
   8:    

   1:  
   2:  class MyClass {
   3:    static count = 0;
   4:    static increment() {
   5:      MyClass.count++;
   6:    }
   7:  }
   8:    

26. Readonly Properties

   1:  
   2:  class Circle {
   3:    readonly PI = 3.14;
   4:    readonly radius: number;
   5:    
   6:    constructor(radius: number) {
   7:      this.radius = radius;
   8:    }
   9:  }
  10:    

   1:  
   2:  class Circle {
   3:    PI = 3.14;
   4:    constructor(radius) {
   5:      Object.defineProperty(this, 'radius', {
   6:        value: radius,
   7:        writable: false
   8:      });
   9:    }
  10:  }
  11:    

27. Optional and Mandatory Properties

   1:  
   2:  interface Config { url: string; timeout?: number }
   3:  const config: Config = { url: "/api" }; // timeout optional
   4:  const badConfig = { url: "/api", timeout: "1000" }; // timeout must be number
   5:    

   1:  
   2:  // JS runtime check
   3:  function createUser(user) {
   4:    if (!user.id) throw new Error("Missing required 'id'");
   5:    return { id: user.id, name: user.name || "Anonymous" };
   6:  }
   7:    

OR


   1:  
   2:  // JS define default value
   3:  function createUser({ id, name = "Anonymous" }) {
   4:    return { id, name };
   5:  }
   6:    

28. Index properties

   1:  
   2:  class StringArray {
   3:    [index: number]: string; // Explicit index signature
   4:  
   5:    constructor() {
   6:      this.data = {};
   7:    }
   8:  
   9:    setItem(index: number, value: string) {
  10:      this.data[index] = value; // OK
  11:    }
  12:  
  13:    getItem(index: number): string {
  14:      return this.data[index];
  15:    }
  16:  }
  17:  
  18:  const arr = new StringArray();
  19:  arr.setItem(0, "hello"); // ✅ Valid
  20:  arr.setItem(1, 123); // ❌ Error: Type 'number' is not assignable to type 'string'
  21:    

   1:  
   2:  class StringArray {
   3:    constructor() {
   4:      this.data = {};
   5:    }
   6:  
   7:    // JavaScript allows indexed access (but no type enforcement)
   8:    setItem(index, value) {
   9:      this.data[index] = value;
  10:    }
  11:  
  12:    getItem(index) {
  13:      return this.data[index];
  14:    }
  15:  }
  16:  
  17:  const arr = new StringArray();
  18:  arr.setItem(0, "hello");
  19:  console.log(arr.getItem(0)); // "hello"
  20:  arr.setItem(1, 123); // No error (JavaScript doesn't enforce types)
  21:    

Class inheritance:

29. Abstract Abstract Classes and Methods (TS only)

   1:  
   2:  abstract class Animal {
   3:    abstract makeSound(): void;
   4:    
   5:    move(): void {
   6:      console.log("Moving...");
   7:    }
   8:  }
   9:    

   1:  
   2:  //must use workarounds
   3:  class Animal {
   4:    makeSound() {
   5:      throw new Error("Abstract method not implemented");
   6:    }
   7:  }
   8:    

30. Inheritance and Overriding

   1:  
   2:  class Base {
   3:    greet(): void {
   4:      console.log("Hello!");
   5:    }
   6:  }
   7:  // override keyword and type checking
   8:  class Derived extends Base {
   9:    override greet(): void {
  10:      console.log("Hi!");
  11:    }
  12:  }
  13:    

   1:  
   2:  class Base {
   3:    greet() {
   4:      console.log("Hello!");
   5:    }
   6:  }
   7:  // no override checking
   8:  class Derived extends Base {
   9:    greet() {  // No override keyword
  10:      console.log("Hi!");
  11:    }
  12:  }
  13:    

Interface:

31. Interface Implementation (TS only)

   1:  
   2:  interface Serializable {
   3:    serialize(): string;
   4:  }
   5:  
   6:  class MyClass implements Serializable {
   7:    serialize(): string {
   8:      return JSON.stringify(this);
   9:    }
  10:  }
  11:    

Generic:

32. Generic Classes (TS only)

   1:  
   2:  class Box<T> {
   3:    contents: T;
   4:    constructor(value: T) {
   5:      this.contents = value;
   6:    }
   7:  }
   8:    

   1:  
   2:  function echo<T>(value: T): T {
   3:    return value;
   4:  }
   5:  const result = echo<string>("Hello"); // Explicit type
   6:  const result2 = echo(123); // Inferred as number
   7:    

   1:  
   2:  function echo(value) {
   3:    return value;
   4:  }
   5:  const result = echo("Hello"); // Javascript - No type constraints
   6:    

Decorator:

33. Decorators (TS only)

   1:  
   2:  @sealed
   3:  class Greeter {
   4:    greeting: string;
   5:    
   6:    constructor(message: string) {
   7:      this.greeting = message;
   8:    }
   9:  }
  10:    

JavaScript (stage 3 proposal):


   1:  
   2:  @sealed
   3:  class Greeter {
   4:    @configurable(false)
   5:    greeting;
   6:  }
   7:    

Immutable Objects:

34. Immutable Objects

   1:  
   2:  const user = { name: "Alice" } as const;
   3:  user.name = "Bob"; // ❌ Error: readonly property
   4:    

   1:  
   2:  const user = { name: "Alice" };
   3:  user.name = "Bob"; // ✅ Javascript - Allowed
   4:    

Operators:

35. Keyof Operator (TS only)

   1:  
   2:  type Person = { name: string; age: number };
   3:  type PersonKeys = keyof Person; // "name" | "age"
   4:  
   5:  function getProperty(obj: Person, key: PersonKeys) {
   6:    return obj[key];
   7:  }
   8:    

   1:  
   2:  function getProperty(obj, key) {
   3:    if (key in obj) {
   4:      return obj[key];
   5:    }
   6:    throw new Error("Invalid key");
   7:  }
   8:    

OR

   1:  
   2:  function getProperty<T, K extends keyof T>(obj: T, key: K) {
   3:    return obj[key]; // 100% type-safe
   4:  }
   5:  getProperty({ name: "Alice" }, "name"); // ✅
   6:  getProperty({ name: "Alice" }, "age"); // ❌ Error
   7:    

   1:  
   2:  function getProperty(obj, key) {
   3:    return obj[key]; // No safety
   4:  }
   5:  getProperty({ name: "Alice" }, "age"); // ❌ Returns undefined (silent failure)
   6:    

36. Optional Chaining (?.) vs TypeScript's Optional Properties

   1:  
   2:  type User = {
   3:    name: string;
   4:    address?: { // Optional property
   5:      city: string;
   6:    }
   7:  };
   8:  
   9:  const user: User = { name: 'Alice' };
  10:  const city = user.address?.city; // TS understands optional chains
  11:    

   1:  
   2:  const user = { name: 'Alice' };
   3:  const city = user.address?.city; // Works in modern JS, but no type checking
   4:    

37. Non-Null Assertion Operator (!)

   1:  
   2:  const element = document.getElementById('root')!; // No null-check needed
   3:  element.innerHTML = 'Hello'; // Safe (according to TS)
   4:    

   1:  
   2:  const element = document.getElementById('root');
   3:  if (element) { // Required in JS
   4:    element.innerHTML = 'Hello';
   5:  }
   6:    

38. Strict Null Checks (TS only)

   1:  
   2:  // TypeScript (with strictNullChecks)
   3:  let name: string;
   4:  console.log(name.length); // Error: 'name' is possibly undefined
   5:    

   1:  
   2:  let name;
   3:  console.log(name.length); // // JavaScript Runtime error: Cannot read property 'length' of undefined
   4:    

Type manipulation:

39. Type Aliases (TS only)

   1:  
   2:  class StringArray {
   3:    [index: number]: string; // Explicit index signature
   4:  
   5:    constructor() {
   6:  // TypeScript
   7:  type User = {
   8:    id: string | number;
   9:    name: string;
  10:  };
  11:    

   1:  
   2:  // JavaScript JSDoc
   3:  /**
   4:   * @typedef {Object} User
   5:   * @property {string | number} id
   6:   * @property {string} name
   7:   */
   8:    

40. Union Types (TS only)

   1:  
   2:  let result: string | number;
   3:    

41. Intersection Types (TS only)

   1:  
   2:  type Admin = User & { permissions: string[] };
   3:    

42. Type Assertions (TS only)

   1:  
   2:  const element = document.getElementById('root') as HTMLElement;
   3:    

OR

   1:  
   2:  const input = <HTMLInputElement>document.getElementById('input');
   3:    

43. Utility Types (Partial<T>, Pick<T, K>) (TS only)

   1:  
   2:  type User = {
   3:    id: number;
   4:    name: string;
   5:    email: string;
   6:  };
   7:  
   8:  // Partial<T> - Makes all properties optional
   9:  type PartialUser = Partial<User>;
  10:  /* Equivalent to:
  11:     { id?: number; name?: string; email?: string } */
  12:  
  13:  // Pick<T, K> - Select specific properties
  14:  type UserNameOnly = Pick<User, 'name'>; // { name: string }
  15:    

44. Conditional Types (T extends U ? X : Y) (TS only)

   1:  
   2:  type IsString<T> = T extends string ? true : false;
   3:  
   4:  type A = IsString<"hello">; // true
   5:  type B = IsString<123>;     // false
   6:    

45. Branded Types (nominal typing) (TS only)

   1:  
   2:  type UserID = string & { __brand: "UserID" };
   3:  function createUser(id: UserID) { ... }
   4:    

   1:  
   2:  function createUser(id) { ... } // Any string can pass
   3:    

   1:  
   2:  type Meters = number & { __brand: "Meters" };
   3:  type Seconds = number & { __brand: "Seconds" };
   4:    

   1:  
   2:  // Example: Add an invisible "sticker" to the type
   3:  type UserID = string & { __brand: "UserID" };
   4:  type OrderID = string & { __brand: "OrderID" };
   5:  
   6:  // Helper function to apply the "sticker"
   7:  function createUserID(id: string): UserID {
   8:    return id as UserID; // Trust me, this is a UserID
   9:  }
  10:  
  11:  // Usage
  12:  const userId = createUserID("user_123"); // ✅ Properly branded
  13:  const orderId = "order_456" as OrderID;  // ✅ (alternative syntax)
  14:  
  15:  function processUser(id: UserID) {...}
  16:  
  17:  processUser(userId); // ✅ Works
  18:  processUser(orderId); // ❌ Error: Not a UserID!
  19:    

Execute TS:

Browser can execute only JS, but Vite server or WebPack can automatically transform TS to JS :

<script lang="ts">
    ...
</script>

Vite Webpack (ts-loader) Webpack (babel-loader)
Speed ⚡ Fastest (esbuild) 🐢 Slow (full TS compilation) ⚡ Fast (Babel)
Type Checking ❌ No (unless vite-plugin-checker) ✅ Yes ❌ No
Zero Config ✅ Yes ❌ No ❌ No
HMR (Hot module reload) ✅ Excellent ✅ Good ✅ Good
Advanced TS Features: ⚠ May need plugins ✅ Full support ⚠ Some limitations
Decorators (@Component) ⚠ Needs config ✅ Yes ⚠ With plugin
Const Enums ✅ Yes ✅ Yes ❌ No (converted)
Namespaces ✅ Yes ✅ Yes ⚠ Limited
Custom JSX Factories ✅ Yes ✅ Yes ⚠ Needs plugin
emitDecoratorMetadata ❌ No ✅ Yes ❌ No
Satisfies Operator ✅ Yes ✅ Yes ✅ Yes (Babel 7.21+)
Template Literal Types ✅ Yes ✅ Yes ❌ Stripped
Best For Modern projects, quick start Strict type checking needed Existing Babel setups, speed focus



AngularTypesctiptLearning context:



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