Hone logo
Hone
Problems

Advanced Module Resolution with Custom Types in TypeScript

TypeScript's module resolution system is powerful, but sometimes you need more control, especially when dealing with non-standard module formats or custom build processes. This challenge asks you to create a custom module resolution type that allows you to resolve modules based on a specific, configurable mapping. This is useful for scenarios like resolving modules from a CDN, using a custom package registry, or handling legacy module formats.

Problem Description

You need to implement a CustomModuleResolver type that extends TypeScript's ModuleResolution interface. This resolver will take a moduleMap as a constructor parameter. The moduleMap is an object where keys are module specifiers (strings) and values are the resolved module paths (strings). The resolver should prioritize the moduleMap over the default module resolution behavior. If a module specifier is found in the moduleMap, it should return the corresponding resolved path. Otherwise, it should delegate to the default ModuleResolution.resolveModule.

Key Requirements:

  • Extend ModuleResolution: Your type must extend the ModuleResolution interface.
  • moduleMap: The constructor must accept a moduleMap object ( { [key: string]: string }).
  • Prioritized Resolution: The resolver should first check the moduleMap. If a match is found, return the mapped path.
  • Fallback to Default: If no match is found in the moduleMap, delegate to the default ModuleResolution.resolveModule method.
  • Correct this context: Ensure this refers to the CustomModuleResolver instance when calling resolveModule.

Expected Behavior:

When given a module specifier, the resolver should:

  1. Check if the specifier exists as a key in the moduleMap.
  2. If it exists, return the corresponding value (resolved path) from the moduleMap.
  3. If it doesn't exist, call the default resolveModule method with the same specifier and return its result.

Edge Cases to Consider:

  • Empty moduleMap: Should not cause errors; fallback to default resolution.
  • Circular dependencies within the moduleMap (e.g., "a" maps to "b" and "b" maps to "a"). This challenge does not require you to detect or handle circular dependencies. Assume the map is valid.
  • Specifiers that are relative paths (e.g., "./foo"). The resolver should handle these correctly by delegating to the default resolver.
  • Specifiers that are absolute paths.

Examples

Example 1:

Input: moduleMap = { "my-module": "path/to/my-module.ts" }, specifier = "my-module"
Output: "path/to/my-module.ts"
Explanation: The specifier "my-module" is found in the moduleMap, so the corresponding value is returned.

Example 2:

Input: moduleMap = { "my-module": "path/to/my-module.ts" }, specifier = "another-module"
Output: "node_modules/another-module/index.ts" (or similar, depending on default resolution)
Explanation: The specifier "another-module" is not found in the moduleMap, so the default resolver is called.

Example 3:

Input: moduleMap = {}, specifier = "any-module"
Output: "node_modules/any-module/index.ts" (or similar, depending on default resolution)
Explanation: The moduleMap is empty, so the default resolver is called.

Constraints

  • The moduleMap will always be a plain JavaScript object.
  • Module specifiers and resolved paths will be strings.
  • Performance is not a primary concern for this challenge. Focus on correctness and clarity.
  • You are not required to implement the entire ModuleResolution interface, only the resolveModule method.

Notes

  • You'll need to understand the basic structure of TypeScript's ModuleResolution interface. Refer to the TypeScript documentation for details.
  • Consider using a class to implement the CustomModuleResolver to properly manage the moduleMap and this context.
  • This challenge focuses on the core logic of module resolution. Error handling and more complex scenarios are beyond the scope of this exercise.
  • The default resolveModule method is assumed to be available and functional. You don't need to implement it.
Loading editor...
typescript