Transitioning from JavaScript to TypeScript for Enhanced Software Compatibility

Introduction

Welcome to today's lesson, where we will tackle a common challenge in software engineering: introducing complex features while preserving backward compatibility. We'll use a Potluck Dinner organization system as our backdrop, embarking on a fascinating journey of TypeScript programming, step-by-step analysis, and strategic thinking. Are you ready? Let's begin our adventure!

Starter Task Review

Initially, our Potluck Dinner organization system enables us to add and remove participants and manage their respective dishes for each round. There are three critical methods with type specifications:

  • addParticipant(memberId: string): boolean: This method adds a participant. If a participant with the given memberId already exists, it won't create a new one but will return false. Otherwise, it will add the member and return true.
  • removeParticipant(memberId: string): boolean: This method removes a participant with the given memberId. If the participant exists, the system will remove them and return true. Otherwise, it will return false. When removing a participant, you need to remove their dish if they brought one.
  • addDish(memberId: string, dishName: string): boolean: This method enables each participant to add their dishes for every round. If a participant has already added a dish for this round or if the memberId isn't valid, the method will return false. Otherwise, it will add the dish for the respective participant's round and return true.

Let's write our TypeScript code, which implements the functions as per our initial state:

class Potluck {
    private participants: Set<string>;
    private dishes: Record<string, string>;

    constructor() {
        this.participants = new Set<string>();
        this.dishes = {};
    }
    
    addParticipant(memberId: string): boolean {
        if (this.participants.has(memberId)) {
            return false;
        } else {
            this.participants.add(memberId);
            return true;
        }
    }
    
    removeParticipant(memberId: string): boolean {
        if (!this.participants.has(memberId)) {
            return false;
        } else {
            this.participants.delete(memberId);
            delete this.dishes[memberId];
            return true;
        }
    }
    
    addDish(memberId: string, dishName: string): boolean {
        if (!this.participants.has(memberId) || this.dishes.hasOwnProperty(memberId)) {
            return false;
        } else {
            this.dishes[memberId] = dishName;
            return true;
        }
    }
}

In this code, we use the following Data Structures:

  • participants: Set<string>: This ensures that participant IDs remain unique. Using a Set simplifies membership checks (.has) and additions (.add) with O(1)O(1) complexity.
  • dishes: Record<string, string>: Maps each participant's ID to their dish. This structure allows efficient key-value lookups and updates.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal