Skip to content

Feature request: Cleaner handling of TypeScript type-only import elision on externally imported registrations #14

@cmidgley

Description

@cmidgley

I commonly encounter a situation where I get errors because TypeScript has removed the value-import because it thinks it is a type-only import. For example, a fairly typical index.ts for a module might be:

import { MyImplementation } from './MyCode.js';
export type { MyInterface } from './types.js';

container.registerSingleton<MyInterface, MyImplementation>();

This commonly will fail because TypeScript removes what it believes is a type-only import (I think before passing to the transformer), so when the generated code then tries to reference MyImplementation as a value, it gets an error that it doesn't exist.

The work-around is to reference MyImplementation somewhere in the file, for which I've added a global namespace function retainValue:

import { MyImplementation } from './MyCode.js';
export type { MyInterface } from './types.js';

retainValue(MyImplementation);
container.registerSingleton<MyInterface, MyImplementation>();

My proposal is to extend the interface and the compiler to support this syntax:

container.registerSingleton<MyInterface>(MyImplementation);

This seems straightforward in the DI types and has little change there. The heavier lifting would be in DI-compiler as it would need to know the implementation is a class and generate the same registerSingleton(undefined, { identifier: "MyImplementation", implementation: MyImplementation }) that the other usage does. This would be superior to using registerSingleton<MyInterface>(() => new MyImplementation()); as it would use injected properties for the new class instance.

I'm not proposing to eliminate the current syntax, but instead extend the definition of "implementation" to be a function OR a class.


P.S. The test script no longer works on Windows due to switching DI and DI-compiler to Node's built-in testing feature. The tests run fine, but Node / the Windows shell does not provide glob expansion, so the test names don't match. Not your bug, but FYI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions