DEV Community

Cover image for Building Stronger Foundations with TypeScript: Insights and Takeaways
kebin20
kebin20

Posted on • Edited on

Building Stronger Foundations with TypeScript: Insights and Takeaways

A few months ago, I set out to learn TypeScript, as I had heard that it was a highly sought-after skill in Frontend jobs. Initially, I was intimidated by the idea of learning a whole new language, and I thought I needed to be extremely comfortable with my JavaScript skills before diving in. However, to my surprise, TypeScript was more similar to JavaScript than I had anticipated. The only difference was that TypeScript allowed me to declare types to my variables, providing an extra layer of safety to my code.

As I progressed in my TypeScript learning journey, I discovered that it had several benefits that greatly enhanced my understanding of JavaScript and made my code more robust:

  1. Reinforcing main concepts
    TypeScript really helped reinforce the basic concepts of JavaScript, such as primitives, as well as learning other concepts such as Tuples, Unions, interfaces, and types, and many more!

  2. Preventing errors as early as possible
    TypeScript caught many potential errors that could have happened instantly, rather than finding out the errors during build time or after creating a long function and later testing it out to find that the function broke the app and after debugging for many hours.

  3. Making your code more readable
    TypeScript gives better context and readability to your code. With all of the data, functions, and variables flowing in your code, it just makes it easier for another person to go into your code and understand it once the types for these data are declared. It also helps a lot for when you revisit an old project that you haven't touched for a long time and become familiar with it quickly.


Interfaces and Type Aliases

When working with TypeScript, there are a few key tools that I rely on heavily. At the top of that list are interfaces and type aliases. These features have been a game-changer for me when defining complex data structures that have multiple nested properties.

In the past, it was all too easy to get lost in the code and lose track of what data was being passed around. However, with interfaces and type aliases, I can easily define a clear and concise structure for my data. This makes it much easier to read, understand, and maintain my code over time.

When defining an interface, you use the interface keyword to specify the shape of the object and declare the types of each property. This allows you to easily understand what data is being passed and what data types are used. For example, consider the following interface for an Apple object:


interface apple {
  color: string;
  noOfSeeds: number;
  isExpensive: boolean;
  kinds: string[]
}

Enter fullscreen mode Exit fullscreen mode

In this case, the Apple interface specifies that an Apple object has three properties: color, size, and isTasty, with their respective data types.

Type aliases work in a similar way, but instead of using the interface keyword, you use the type keyword. For instance, you can create a type alias for the Apple interface as follows:


type apple = {
  color: string;
  noOfSeeds: number;
  isExpensive: boolean;
  kinds: {
    name: string,
    latinName: string,
  }[]
}

Enter fullscreen mode Exit fullscreen mode

Type aliases can also be used within an interface to simplify and shorten the code. For instance, consider the following example:


type AppleKinds {
  name: string,
  latinName: string,
}

Enter fullscreen mode Exit fullscreen mode

interface Apple {
  color: string;
  noOfSeeds: number;
  isExpensive: boolean;
  kinds: AppleKinds[];
}

Enter fullscreen mode Exit fullscreen mode

In this way, we have defined the AppleKinds type once and can reuse them within the Apple interface


Key Difference

Through my studies, I discovered a significant difference between type aliases and interfaces - interfaces can be extended, but type aliases cannot. This means that interfaces can inherit the properties of another interface and add new properties, methods, or index signatures to it.

Here's an example of how to extend an interface:


interface Fruit {
 shape: string;
 organic: boolean;
 country: string;
}

interface Apple extends Fruit {
  color: string;
  noOfSeeds: number;
  isExpensive: boolean;
  kinds: AppleKinds[];
}

Enter fullscreen mode Exit fullscreen mode

In this example, the Apple interface is created by extending the Fruit interface and adding new properties such as color, noOfSeeds, isExpensive, and kinds.

On the other hand, trying to extend a type alias would result in an error:


interface Fruit {
 shape: string;
 organic: boolean;
 country: string
}

type Apple extends Fruit {
  color: string;
  noOfSeeds: number;
  isExpensive: boolean;
  kinds: AppleKinds[];
}

//Error log: error TS1110: Type expected.

Enter fullscreen mode Exit fullscreen mode

Since type is used to create a new type, rather than extend an existing one, extending a type alias in this way is not allowed.

To conclude, while there is still much more to learn about TypeScript, I am excited to continue exploring its various features and concepts in my learning journey as I work on new projects. By using TypeScript in my projects, I was able to solidify my understanding of its basic concepts and appreciate the many benefits it offers for developers, including preventing errors early on, reinforcing main concepts, and making code more readable. As I continue to work with TypeScript, I look forward to discovering even more ways it can improve my development workflow and create better, more reliable projects.

Thank you for reading!

Image credit by Image by pikisuperstar on Freepik

Top comments (0)