Hone logo
Hone
Problems

Row Polymorphism in TypeScript

Row polymorphism allows you to treat objects with different types as if they share a common structure, enabling more flexible and reusable code. This challenge asks you to implement a system that allows you to work with a collection of objects, each potentially having a different set of properties, but all conforming to a defined "row" structure. This is particularly useful when dealing with data from various sources or APIs where the schema might not be entirely consistent.

Problem Description

You need to create a TypeScript system that enables row polymorphism. This system should allow you to define a base "row" type and then create multiple specific types that extend this base type with additional properties. The core functionality should be a function that accepts an array of these polymorphic row objects and processes them in a way that respects their individual types.

Specifically, you need to:

  1. Define a Base Row Type: Create a type called BaseRow with a common property id: string.
  2. Define Specific Row Types: Create at least three specific row types (RowTypeA, RowTypeB, RowTypeC) that extend BaseRow. Each of these types should have unique properties in addition to the id property. For example:
    • RowTypeA: id: string, name: string
    • RowTypeB: id: string, age: number
    • RowTypeC: id: string, city: string, country: string
  3. Create a Polymorphic Row Type: Define a type PolymorphicRow that represents a union of all the specific row types (including BaseRow if it's not already implicitly included).
  4. Implement a Processing Function: Create a function called processRows that accepts an array of PolymorphicRow objects. This function should iterate through the array and, for each row, perform a type-specific action based on its type. The actions should be:
    • If the row is RowTypeA, log "Processing RowTypeA: {name}".
    • If the row is RowTypeB, log "Processing RowTypeB: {age}".
    • If the row is RowTypeC, log "Processing RowTypeC: {city}, {country}".
    • If the row is BaseRow (and not one of the specific types), log "Processing BaseRow: {id}".

Examples

Example 1:

Input: [
  { id: "1", name: "Alice" },
  { id: "2", age: 30 },
  { id: "3", city: "New York", country: "USA" },
  { id: "4" }
]
Output:
"Processing RowTypeA: {name}"
"Processing RowTypeB: {age}"
"Processing RowTypeC: {city}, {country}"
"Processing BaseRow: {id}"
Explanation: The `processRows` function iterates through the array, identifies the type of each object, and logs the appropriate message based on its type.

Example 2:

Input: [
  { id: "5", name: "Bob" },
  { id: "6" }
]
Output:
"Processing RowTypeA: {name}"
"Processing BaseRow: {id}"
Explanation:  Only the first object has the `name` property, so only it is processed as `RowTypeA`. The second object only has the `id` property, so it's processed as `BaseRow`.

Example 3: (Edge Case - Empty Array)

Input: []
Output: (No output)
Explanation: The `processRows` function should handle an empty array gracefully without errors.

Constraints

  • The input array to processRows can contain a mix of RowTypeA, RowTypeB, RowTypeC, and BaseRow objects.
  • The id property is always present in all row types.
  • The processRows function should not throw errors if it encounters an unexpected row type (though handling it gracefully is preferred).
  • The solution should be type-safe and leverage TypeScript's type system effectively.

Notes

  • Consider using type guards (e.g., isRowTypeA, isRowTypeB, isRowTypeC) to determine the type of each row within the processRows function. These guards can be implemented using in operator checks.
  • The goal is to demonstrate an understanding of TypeScript's type system and how to work with union types and type guards to achieve row polymorphism.
  • Focus on clarity and readability in your code. Well-commented code is appreciated.
  • While performance isn't a primary concern for this challenge, avoid unnecessarily complex or inefficient solutions.
Loading editor...
typescript