如何从TypeScript函数返回类?

时间:2016-02-10 11:36:00

标签: javascript angularjs dependency-injection typescript

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

这就是我在ES6中注册课程的方法

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

如果我在TypeScript中写相同的内容:

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

无法使用错误编译

  

错误TS4025:导出变量' factory'拥有或正在使用私人名称' Foo'。

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

7 个答案:

答案 0 :(得分:4)

快速回答

改变这个:

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

到那个:

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

更长的答案

可以通过 tsconfig.json 设置触发/强制此错误:

{
    "compilerOptions": {
        ...
        "declaration": true // this should be false or omitted

但这不是原因,它只是一个触发器。真正的原因(如此处讨论Error when exporting function that returns class: Exported variable has or is using private name)来自Typescript编译器

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

let factory = () => { ...

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

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

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

return class Foo {} // this is returned value, 
                    // that could be treated as a return type of the factory method

所以,如果我们有类似的声明(这是与原始声明不一样,但是我们只是试着用它作为一个例子来澄清会发生什么)我们可以正确地声明返回类型:

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 let factory = () : IFoo => {
    return class Foo implements IFoo {}
};

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

我正在努力解决同样的错误。我的解决方案是删除

"declaration": true

来自tsconfig.json或将其设置为false

答案 3 :(得分:1)

我发现 separately provided solution 很满意:

export class MyClass {
   ...
}

export type MyClassRef = new (...args: any) => MyClass;

鉴于该签名,我可以使用 MyClassRef 作为一种返回值:

exposeMyClass(): MyClassRef {
    return MyClass;
}

答案 4 :(得分:0)

我认为这是正确的做法:

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

Check it out on playground

答案 5 :(得分:0)

对旧问题的迟到回答:

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

class Foo {}

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

答案 6 :(得分:-2)

您是否正在寻找函数返回的类型?下面是一个代码片段,我们如何在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());