Avoid Using Wildcard Imports
What is it?
This practice warns against the use of wildcard imports in TypeScript. Wildcard imports, such as using "import * as", pull in all exported members from a module, making it unclear which specific exports are being utilized. This ambiguity can make code harder to read, maintain, and refactor.
Why apply it?
Explicitly listing the imported members: • Improves code readability by making dependencies clear. • Reduces the risk of namespace collisions. • Helps maintainers understand the module dependencies without having to inspect the imported module itself. • Limits the exposure of internal module details by only importing what is necessary.
How to Fix it?
Replace wildcard imports with explicit named imports. List exactly what you need from the module rather than importing everything.
Examples
Example 1:
Negative
Incorrect implementation that violates the practice.
import * as Imported from "aModule"; // Noncompliant
function processData(data: Imported.aType): void {
if (Imported.aFunction(data)) {
console.log(Imported.aConstant);
} else {
console.error("Processing failed!");
}
}
const item: Imported.aType = { key: "value" };
processData(item);
Example 2:
Positive
Correct implementation following the practice.
// In util.ts
export const helper = (): string => {
return "Helper function executed";
};
export const version = "1.0.0";
export class UtilClass {
log(message: string): void {
console.log("Log:", message);
}
}
// In index.ts
import { helper, UtilClass } from "./util";
console.log(helper());
const utilInstance = new UtilClass();
utilInstance.log("Initialization complete");
Negative
Incorrect implementation that violates the practice.
import * as ConfigModule from "./config"; // Noncompliant
function initApp(config: ConfigModule.ConfigType): void {
const logger: ConfigModule.Logger = new ConfigModule.Logger();
logger.info("Application initialization started.", config);
// Additional initialization logic...
logger.info("Application successfully initialized.");
}
const config = { env: "production", debug: false, apiEndpoint: "https://api.example.com" };
initApp(config);
Example 3:
Positive
Correct implementation following the practice.
import { Logger, ConfigType } from "./config";
function initApp(config: ConfigType): void {
const logger: Logger = new Logger();
logger.info("Application initialization started.", config);
// Additional initialization logic...
logger.info("Application successfully initialized.");
}
const config = { env: "production", debug: false, apiEndpoint: "https://api.example.com" };
initApp(config);
Negative
Incorrect implementation that violates the practice.
// In util.ts
export const helper = (): string => {
return "Helper function executed";
};
export const version = "1.0.0";
export class UtilClass {
log(message: string): void {
console.log("Log:", message);
}
}
// In index.ts
export * from "./util"; // Noncompliant
// Consumers now receive unintended exports like 'version'
Example 4:
Positive
Correct implementation following the practice.
import { aType, aFunction, aConstant } from "aModule";
function processData(data: aType): void {
if (aFunction(data)) {
console.log(aConstant);
} else {
console.error("Processing failed!");
}
}
const item: aType = { key: "value" };
processData(item);