The confusing parts of TypeScript

The confusing parts of TypeScript

Intro

Learning TS and having a layer of protection to catch type-based errors was one of the biggest motivations to adopt TS. This an awesome tool to have in your pocket. in this article I would refer to some parts of the typescript that might be confusing to you if you new to TS, all of them have been asked on Stackoverflow. I tried to form the thoughts in a clear way that should remove vagueness and incompleteness. Down below are the references I use to write this article. The confusion comes from several reasons, such as obvious similarity and vague difference, not knowing when to use what, similar variants. let's have a look at them.

private vs protected access modifiers

An access modifier in TypeScript determines who access class property or method.

private access modifier is accessible only from inside the class.

protected access modifier is accessible from inside the class and sub-class as well.

class Parent {
    private privateP: number // or #privateP TS 3.8 supports the new JS syntax
    public publicP: number
    protected protectP: number

    constructor( publicP:number, protectP:number ){
        this.publicP=publicP
        this.protectP=protectP
        this.privateP= this.publicP * this.protectP
    }

    method(){
        // all properties are accessible 
    }
}

new Parent(5,8).publicP // only public props | mothods are accessible

class Subclass extends Parent {
    constructor(publicP:number,protectP:number){ 
        super(publicP, protectP)
    }
    method2(){
        this.protectP
        this.publicP
        this.method
        // this.privateP is not accessabile
    }
}

interface vs class

Similarity:

both do type-checking

Key differences:

interface:

  • Definition: is simply a structural contract that defines what the properties of an object should have as a name and as a type. The typescript compiler uses it solely for type-checking purposes. To be sure an object has the exact properties you want as name and as type then use interface.

  • When type-checking: during design and compile time.

  • When to use: simple type-checking for an object

  • JavaScript output: no

  • syntax:

interface Foo {
a: number
}

Class:

  • Definition: is a blueprint of what an object should look like and act like and then implements that blueprint by initializing the class properties and defining methods.

  • When type-checking: during design, compile-time, and runtime.

  • When to use: needs an extra functionality

  • JavaScript output: yes

  • syntax:

class Foo {
    a: number 
    condtructor(a:number){
        this.a=a
    }
    method (){
        //...
    }
}

interface vs type

Similarity

both are used for type-checking and can be used in some cases interchangeably.

Key differences:

interface

  • Definition: is simply a structural contract that defines what the properties of an object should have as a name and as a type. The typescript compiler uses it solely for type-checking purposes. To be sure an object has the exact properties you want as name and as type then use interface.

  • type-checking: object, function as a method

  • When to use: interface is dedicated to objects and is limited.

  • Compose types: extend

Extend:

// Interface extends interface
interface A { a: number }
interface AB extends A { b: number }

// Interface extends type alias
type A = { a:number }
interface AB extends A { b:number }

implement

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type

  • Definition:

  • type-checking: primitive, object, union, tuple, function

  • When to use: type alias covers all types, but there are conventions that I use to see in codebases and prefer to follow. But it is up to you.

  • Compose types: Intersection (&) and Union types ( | )

Extend:

// type extends type (intersection)
type A { a: number } 
type AB & A { b: number }

// type extends interface
interface A { a: number }
type AB & A { b: number }

implement: a class can implement a type except for type union it throws an error

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// ERROR: A class can only implement an object type or intersection of object types with statically known members
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

Module vs namespace

both are ways to organize our code.

  • a module is a block of code that has its own scope, variables, functions, classes...etc declared in a module are not visible outside the module, unless they are exported using one of the export forms. they can be consumed using one of the import forms
  • module contains code and declaration

  • a namespace is simply named JavaScript object in the global namespace. Unlike modules, namespaces can span multiple files.
  • namespace contains only declarations

extends vs implements

In the context of classes

extends the new class is child, by extending a class we have all its properties and methods implemented out of the box, and we can override them and/or add more.

implements the new class has the same 'shape' as the parent, and the new class has to implement the properties and the methods.

class Foo {
    a:number 
    constructor(a:number){
        this.a =a
    }
}
// extends
class Bar extends Foo {
    b:number
    constructor(a:number,b:number) {
        super(a) // super is required
        this.b= super.a * b
    }
}
// implements
class Baz implements Foo {
    a:number // is required
    b:number
    constructor(a:number){
        this.a= a
        this.b=a*2
    }
}

In the context of interfaces

it is almost the same as in the context of classes but interface has no implementation

interface Foo{
    a:number
}
interface Bar extends Foo{
    b:boolean
}
const obj: Bar= {
  a:3, // both propertries must be provided, no more nor less.
  b:true
}

implement: interfaces have no implementation, only class can implement an interface but not the other way around.

Thank you for reading, share if you like it!


References:

Ultimatecourses

Passionfordev

stackoverflow