Hone logo
Hone
Problems

Gradual Typing System in TypeScript

This challenge asks you to implement a simplified gradual typing system in TypeScript. Gradual typing allows you to mix dynamically typed and statically typed code within the same project, providing flexibility during development while still benefiting from type safety where desired. Your task is to create a system that allows you to annotate variables with optional type information, and then dynamically check these annotations at runtime.

Problem Description

You need to build a function gradualTypeCheck that takes an object as input. This object represents a set of variables, each potentially annotated with a type. The function should perform runtime type checks based on these annotations.

What needs to be achieved:

  • Create a function gradualTypeCheck that accepts an object containing variables and their optional type annotations.
  • Dynamically check the type of each variable against its annotation (if present).
  • Return a boolean indicating whether all type checks passed.
  • Handle cases where a variable has no type annotation (treat as dynamically typed - no check needed).
  • Handle type mismatches gracefully, returning false if any check fails.

Key Requirements:

  • The input object will have keys representing variable names.
  • Each value in the input object will be either:
    • A value of any type (e.g., number, string, boolean, object, array).
    • An object with a value property (the variable's value) and a type property (a string representing the expected type). Valid type strings are: "number", "string", "boolean", "object", "array".
  • The type checking should be performed at runtime.
  • The function should not throw errors; it should return false on type mismatches.

Expected Behavior:

The gradualTypeCheck function should iterate through the input object. For each variable:

  • If the variable has a type annotation, it should perform a runtime type check using typeof or Array.isArray() (for arrays) to verify that the variable's value matches the specified type.
  • If the variable does not have a type annotation, it should skip the type check.
  • If any type check fails, the function should immediately return false.
  • If all type checks pass (or if there are no type annotations), the function should return true.

Edge Cases to Consider:

  • Empty input object.
  • Variables with null or undefined values.
  • Arrays containing mixed types (should be considered a mismatch if the type annotation is "array").
  • Objects with properties of different types (should be considered a mismatch if the type annotation is "object").
  • Invalid type strings in the type annotation (should be treated as dynamically typed - no check needed).

Examples

Example 1:

Input: {
  name: "Alice",
  age: 30,
  isStudent: false,
  grades: [90, 85, 95]
}
Output: true
Explanation: No type annotations are present, so no checks are performed.

Example 2:

Input: {
  name: "Bob",
  age: "25",
  isStudent: true,
  grades: [80, 75, "90"]
}
Output: false
Explanation: `age` is annotated as "number" but its value is a string.  `grades` is annotated as "array" but contains a string.

Example 3:

Input: {
  name: { firstName: "Charlie", lastName: "Brown" },
  age: 20,
  isStudent: false,
  grades: [70, 80, 90],
  address: { street: "123 Main St", city: "Anytown" },
}
Output: false
Explanation: `name` is annotated as "string" but its value is an object. `address` is annotated as "object" but its value is an object.

Example 4:

Input: {
  x: 10,
  y: "hello",
  z: true,
  w: [1, 2, 3],
  a: { a: 1, b: 2 },
  b: null
}
Output: false
Explanation: 'y' is annotated as "number" but is a string. 'w' is annotated as "string" but is an array. 'a' is annotated as "number" but is an object.

Constraints

  • The input object will contain at most 100 variables.
  • Type annotation strings will be one of: "number", "string", "boolean", "object", "array".
  • Variable values can be of any valid JavaScript type.
  • The function must return a boolean value.

Notes

  • Consider using typeof for primitive types (number, string, boolean).
  • Use Array.isArray() to check if a variable is an array.
  • For objects, you can perform a simple check to see if the value is an object using typeof value === 'object' && value !== null. A more robust check would involve verifying the types of the object's properties, but this is beyond the scope of this challenge.
  • Focus on the core logic of runtime type checking. Error handling beyond returning false on mismatch is not required.
  • Think about how to handle cases where the type annotation is invalid. Treating them as dynamically typed is a reasonable approach.
Loading editor...
typescript