I'm using TypeScript with a dependency injection library which works very similar to Angular 1 - basically: register a factory with your dependencies as arguments.
This is how I would register a class in ES6
export let factory = () => { return class Foo {} };
If I write the same in TypeScript:
export let factory = () => { return class Foo {} };
It fails to compile with the error
error TS4025: Exported variable 'factory' has or is using private name 'Foo'.
Is there any way to allow TypeScript to return a class from a factory function?
You need to export the class as well so that the consumer of the method can access the type. Typically a factory will return an instance rather than a class or constructor. export class Foo {}; export let factory = () => { return Foo; };
When you create an object in any function it's destroyed as soon as the function execution is finished just like in variables. But when you return a object from a function firstly compiler creates a local instance of this object in heap called unnamed_temporary then destroyes the object you created.
The function's return type is string. Line function returns a string value to the caller. This is achieved by the return statement. The function greet() returns a string, which is stored in the variable msg.
Use the ReturnType utility type to get the return type of a function in TypeScript, e.g. type T = ReturnType<typeof myFunction> . The ReturnType utility type constructs a type that consists of the return type of the provided function type. Copied!
change this:
export let factory = () => { return class Foo {} };
to that:
export let factory = () : any => { return class Foo {} };
This error could be triggered/forced by to a tsconfig.json setting:
{ "compilerOptions": { ... "declaration": true // this should be false or omitted
But that is not the reason, it is just a trigger. The real reason (as discussed here Error when exporting function that returns class: Exported variable has or is using private name) comes from the Typescript compiler
when TS compiler founds statement like this
let factory = () => { ...
it must start to guess what is the return type, because that information is missing (check the : <returnType>
placeholder):
let factory = () : <returnType> => { ...
in our case, TS will quickly find out, that the returned type
is easy to guess:
return class Foo {} // this is returned value, // that could be treated as a return type of the factory method
so, in case we would have that similar statement (this is not the same, as original statement at all, but let's just try to use it as an example to clarify what happens) we can properly declare return type:
export class Foo {} // Foo is exported export let factory = () : Foo => { // it could be return type of export function return Foo };
that approach would be working, because the Foo
class is exported, i.e. visible to external world.
Back to our case. We want to return type which is not exported. And then, we MUST help TS compiler to decide, what is the return type.
It could be explicit any:
export let factory = () : any => { return class Foo {} };
But even better would be to have some public interface
export interface IFoo {}
And then use such interface as return type:
export let factory = () : IFoo => { return class Foo implements IFoo {} };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With