Hone logo
Hone
Problems

Mastering TypeScript Reference Types: Building a Dynamic User Profile System

TypeScript's powerful type system allows you to define complex data structures. This challenge focuses on leveraging reference types (objects, arrays, and tuples) to build a flexible and type-safe user profile system. Understanding how to define and use these types is fundamental for creating robust applications.

Problem Description

Your task is to design and implement TypeScript types for a user profile system. This system needs to store various pieces of information about users, including their personal details, contact information, and a list of their hobbies. The system should be designed to be extensible, allowing for future additions of more complex user data.

Key Requirements:

  1. Define a User type: This type should encompass a user's id, username, and profile information.
  2. Define a Profile type: This type should include firstName, lastName, age, and contact information.
  3. Define a Contact type: This type should handle multiple ways a user can be contacted, supporting both email and phone numbers. It should be possible for a user to have one or both.
  4. Represent hobbies: Users should have a list of their hobbies, which should be stored as an array of strings.
  5. Use reference types: Ensure that Profile, Contact, and the hobbies list are implemented using appropriate reference types (objects and arrays).

Expected Behavior:

Your TypeScript code should successfully define these types, allowing you to create objects that conform to the User structure. When creating a user object, all required fields must be present, and their types must match the defined structures.

Important Edge Cases:

  • Optional Contact Methods: A user might not have a phone number, or only an email. Your Contact type should gracefully handle missing fields.
  • Empty Hobbies List: A user might have no declared hobbies. The hobbies array should support being empty.

Examples

Example 1:

// Input: Defining a user with email and phone contact, and several hobbies.
const user1: User = {
    id: 1,
    username: "alice_wonder",
    profile: {
        firstName: "Alice",
        lastName: "Wonderland",
        age: 30,
        contact: {
            email: "alice@example.com",
            phone: "123-456-7890"
        }
    },
    hobbies: ["reading", "painting", "hiking"]
};

// Expected Output: The object `user1` should be correctly typed according to the User, Profile, and Contact interfaces.
// No explicit output to console, but type checking should pass.

Explanation: This example demonstrates a typical user scenario with full contact details and multiple hobbies.

Example 2:

// Input: Defining a user with only an email, and an empty hobbies list.
const user2: User = {
    id: 2,
    username: "bob_builder",
    profile: {
        firstName: "Bob",
        lastName: "Builder",
        age: 45,
        contact: {
            email: "bob@example.com"
            // phone is intentionally omitted
        }
    },
    hobbies: [] // No hobbies listed
};

// Expected Output: The object `user2` should be correctly typed.
// Type checking should pass.

Explanation: This example tests the handling of an optional contact method (phone) and an empty hobbies array.

Constraints

  • All types must be defined using TypeScript's interface or type keywords.
  • The id field should be a number.
  • username, firstName, lastName, email, and elements within the hobbies array must be strings.
  • age must be a number.
  • The contact object should be optional within the profile to allow for users with no contact information defined yet.

Notes

  • Consider how to make the phone property within the Contact type truly optional.
  • Think about how to ensure that when contact is present, it's either an object with an email or a phone, or both. (Hint: Union types or optional properties can be useful here).
  • Focus on clearly defining the relationships between your reference types.
  • The goal is to have a type definition that makes it difficult (or impossible) to create invalid user data.
Loading editor...
typescript