Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
190 views
in Technique[技术] by (71.8m points)

javascript - How can I return a class from a TypeScript function?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Quick answer

change this:

export let factory = () => {
    return class Foo {}
};

to that:

export let factory = () : any => {
    return class Foo {}
};

Longer answer

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 {}
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...