Distributed Conditional Types: Type Inference Across Modules
Conditional types in TypeScript allow you to create types that depend on other types. This challenge explores extending this concept to a distributed scenario where the conditional type's dependency is defined in a separate module. This is useful for creating reusable type logic that can be shared across a larger codebase, promoting modularity and type safety.
Problem Description
You are tasked with creating a system that allows a module (Module A) to utilize a conditional type defined in another module (Module B). Module B defines a generic type ConditionalType<T, Condition> which returns T if Condition is truthy, otherwise it returns never. Module A needs to use this ConditionalType to infer a specific type based on a value that might be imported from a third module (Module C).
Specifically, Module A should:
- Import
ConditionalTypefrom Module B. - Import a value (e.g., a boolean) from Module C.
- Use
ConditionalTypefrom Module B, passing in a typeTand the value imported from Module C as theCondition. - Infer a type based on the result of the conditional type.
The challenge is to ensure that TypeScript correctly infers the type based on the imported value, even though the conditional type logic resides in a separate module. You need to demonstrate that the type inference works as expected, and that the code compiles without type errors.
Examples
Example 1:
Module B (conditional-types.ts):
export type ConditionalType<T, Condition extends boolean> =
Condition extends true ? T : never;
Module C (config.ts):
export const enableFeature: boolean = true;
Module A (main.ts):
import { ConditionalType } from './conditional-types';
import { enableFeature } from './config';
type Result = ConditionalType<string, enableFeature>;
// The type of Result should be string
Output: string
Explanation: enableFeature is true, so ConditionalType<string, true> resolves to string.
Example 2:
Module B (conditional-types.ts): (Same as Example 1)
Module C (config.ts):
export const enableFeature: boolean = false;
Module A (main.ts):
import { ConditionalType } from './conditional-types';
import { enableFeature } from './config';
type Result = ConditionalType<number, enableFeature>;
// The type of Result should be never
Output: never
Explanation: enableFeature is false, so ConditionalType<number, false> resolves to never.
Example 3: (More complex type)
Module B (conditional-types.ts): (Same as Example 1)
Module C (config.ts):
export const enableFeature: boolean = true;
Module A (main.ts):
import { ConditionalType } from './conditional-types';
import { enableFeature } from './config';
type MyType = { a: string; b: number };
type Result = ConditionalType<MyType, enableFeature>;
// The type of Result should be MyType
Output: { a: string; b: number; }
Explanation: enableFeature is true, so ConditionalType<MyType, true> resolves to MyType.
Constraints
- All code must be valid TypeScript.
- You must use the provided
ConditionalTypefrom Module B. Do not redefine it. - Module A must correctly infer the type based on the value imported from Module C.
- The solution should be modular and demonstrate clear separation of concerns between the modules.
- The code should compile without any type errors.
- Assume that the file paths for the modules are correctly configured within your TypeScript project (e.g., using
tsconfig.json).
Notes
- This challenge focuses on type inference and the ability to use conditional types defined in separate modules.
- Consider how TypeScript resolves types across module boundaries.
- The
Conditiontype is constrained tobooleanto simplify the problem. - Think about how the
enableFeaturevalue from Module C influences the type inference in Module A. The key is to ensure that TypeScript correctly propagates the boolean value as a type parameter to the conditional type. - You don't need to write any runtime code; this is purely a type-level challenge. The goal is to demonstrate that the type inference works as expected.