Javascript 如何从TypeScript函数返回类?

Javascript 如何从TypeScript函数返回类?,javascript,angularjs,dependency-injection,typescript,Javascript,Angularjs,Dependency Injection,Typescript,我将TypeScript与依赖项注入库一起使用,它的工作原理与Angular 1非常相似——基本上是:使用依赖项作为参数注册工厂 这是我在ES6中注册类的方式 export let factory = () => { return class Foo {} }; 如果我用TypeScript写同样的内容: export let factory = () => { return class Foo {} }; 它无法编译,并出现错误 错误TS4025:导出的变量“f

我将TypeScript与依赖项注入库一起使用,它的工作原理与Angular 1非常相似——基本上是:使用依赖项作为参数注册工厂

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

export let factory = () => {
    return class Foo {}
};
如果我用TypeScript写同样的内容:

export let factory = () => {
    return class Foo {}
};
它无法编译,并出现错误

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


是否有任何方法允许TypeScript从工厂函数返回类?

您还需要导出该类,以便该方法的使用者可以访问该类型

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

更新的示例

export class Foo {}; 

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

使用ES6,您不需要导出类类型,但使用TypeScript,您绝对应该导出类型签名。

您是否在寻找从函数返回的类类型?下面是一段代码片段,我们可以使用类似于其他语言的TypeScript实现factory

    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());

我也在为同样的错误而挣扎。对我来说,解决办法是移除

"declaration": true
tsconfig.json
或将其设置为
false

快速回答 更改此项:

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

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

更长的答案 此错误可能由以下设置触发/强制:

但这不是原因,它只是一个触发器。真正的原因(如这里所讨论的)来自Typescript编译器

当TS编译器创建这样的语句时

let factory = () => { ...
它必须开始猜测返回类型,因为缺少该信息(请检查占位符):

因此,如果我们有类似的语句(这与原始语句完全不同,但让我们试着用它作为一个例子来澄清发生了什么),我们可以正确地声明返回类型:

export class Foo {} // Foo is exported
export let factory = () : Foo => { // it could be return type of export function
    return Foo
};
这种方法是可行的,因为
Foo
类是导出的,即对外部世界可见的

回到我们的案子我们希望返回类型未导出的。然后,我们必须帮助TS编译器决定返回类型

它可以是明确的:

export let factory = () : any => {
    return class Foo {}
};
但最好是有一些公共接口

export interface IFoo {}
然后使用该接口作为返回类型:

export class Foo {} // Foo is exported
export let factory = () : Foo => { // it could be return type of export function
    return Foo
};

我认为这样做是正确的:

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

我发现令人满意的是:

export class MyClass {
   ...
}

export type MyClassRef = new (...args: any) => MyClass;
给定该签名,我可以使用
MyClassRef
作为返回值的一种类型:

exposeMyClass(): MyClassRef {
    return MyClass;
}

关于老问题的迟交答复:

您需要在工厂方法之外定义类,并使用“typeof”定义返回值

class Foo {}

export const factory = (): typeof Foo => {
    return Foo;
};

回答得好!现在它甚至可以用于声明:true:)然而,你最后的建议正是我在开始时尝试过的——这不起作用:类型“typeof Foo”不能分配给类型“IFoo”。@MiB我想说,这是另一个问题。检查一下这个操场。。。显示出这样的问题。。在这种情况下,if
IFoo
as接口需要一些东西。。哪个
Foo
没有实现。。。在那个例子中,
IFoo{x:boolean}
需要x,但类没有它
class Foo实现IFoo{}
希望它有助于bitI猜测这是真的,但在我的例子中添加
public x:boolean=false
类Foo
仍然会导致相同的错误。考虑到返回动态生成的类(例如React HOC)的用例,检查没有太大帮助。最初的问题是关于在typescript中实现工厂模式(使用AngularJS),并解决编译器错误。它没有说明如何生成一个动态生成的类。@Martin这个问题实际上只包含一个动态类的示例。@MarcJ.Schmidt是的,这是因为ES6是一种动态语言,其中的问题是如何在TypeScript中实现它——它添加了类型签名。
export class MyClass {
   ...
}

export type MyClassRef = new (...args: any) => MyClass;
exposeMyClass(): MyClassRef {
    return MyClass;
}
class Foo {}

export const factory = (): typeof Foo => {
    return Foo;
};