如何从 TypeScript 函数返回一个类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35314114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:16:30  来源:igfitidea点击:

How can I return a class from a TypeScript function?

javascriptangularjsdependency-injectiontypescript

提问by RiggerTheGeek

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.

我正在使用带有依赖注入库的 TypeScript,它的工作原理与 Angular 1 非常相似 - 基本上:用您的依赖项作为参数注册一个工厂

This is how I would register a class in ES6

这就是我在 ES6 中注册一个类的方式

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

If I write the same in TypeScript:

如果我在 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'.

错误 TS4025:导出的变量“工厂”具有或正在使用私有名称“Foo”。

Is there any way to allow TypeScript to return a class from a factory function?

有没有办法让 TypeScript 从工厂函数返回一个类?

回答by Radim K?hler

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.jsonsetting:

此错误可能由tsconfig.json设置触发/强制:

{
    "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

但这不是原因,它只是一个触发器。真正的原因(如此处讨论的导出返回类的函数时出错:导出的变量具有或正在使用私有名称)来自 Typescript 编译器

when TS compiler founds statement like this

当 TS 编译器发现这样的语句时

let factory = () => { ...

it must start to guess what is the return type, because that information is missing (check the : <returnType>placeholder):

它必须开始猜测返回类型是什么,因为缺少该信息(检查: <returnType>占位符)

let factory = () : <returnType> => { ...

in our case, TS will quickly find out, that the returned typeis easy to guess:

在我们的例子中,TS 会很快发现,返回的type很容易猜到:

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 statementat 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 Fooclassis exported, i.e. visible to external world.

这种方法会起作用,因为该类是导出的,即对外部世界可见。Foo

Back to our case. We wantto return typewhich is not exported. And then, we MUST help TS compiler to decide, what is the return type.

回到我们的案例。我们希望返回类型这是不出口。然后,我们必须帮助 TS 编译器决定返回类型是什么。

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

回答by Martin

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.

通常,工厂将返回一个实例而不是类或构造函数。

回答by MiB

I was struggling with the same error. The solution for me was to remove the

我正在为同样的错误而苦苦挣扎。我的解决方案是删除

"declaration": true

from tsconfig.jsonor to set it to false.

tsconfig.json或 将其设置为false

回答by Joseph Buchma

I think this is a proper way to do it:

我认为这是一个正确的方法:

export let factory = () => {
     class Foo {/* ... */}
     return Foo as (new () => { [key in keyof Foo]: Foo[key] })
};

Check it out on playground

在操场上看看

回答by Joy George Kunjikkuru

Are you looking for returning Type of class from the function? Below is one code snippet how we can implement factory in TypeScript similar to in other languages.

您是否正在寻找从函数中返回类的类型?下面是一个代码片段,我们如何像其他语言一样在 TypeScript 中实现工厂。

    class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
class Factory{
    getObject(msg:string): Greeter {
        return new Greeter(msg);
    }
}
var greeter = new Factory().getObject("Hi");
console.log(greeter.greet());