如何从 TypeScript 函数返回一个类?
Posted
技术标签:
【中文标题】如何从 TypeScript 函数返回一个类?【英文标题】:How can I return a class from a TypeScript function? 【发布时间】:2016-05-20 17:46:29 【问题描述】:我正在使用 TypeScript 和一个与 Angular 1 非常相似的依赖注入库 - 基本上:注册一个工厂,将你的依赖项作为参数。
这就是我在 ES6 中注册类的方式
export let factory = () =>
return class Foo
;
如果我在 TypeScript 中写同样的话:
export let factory = () =>
return class Foo
;
编译失败,报错
错误 TS4025:导出的变量“工厂”具有或正在使用私有名称“Foo”。
有什么方法可以让 TypeScript 从工厂函数返回一个类?
【问题讨论】:
【参考方案1】:您还需要导出类,以便方法的使用者可以访问该类型。
通常,工厂将返回一个实例而不是类或构造函数。
更新示例
export class Foo ;
export let factory = () =>
return Foo;
;
使用 ES6,您不需要导出类类型,但使用 TypeScript,您绝对应该导出类型签名。
【讨论】:
考虑到返回动态生成的类(例如 React HOC)的用例,这并不是很有帮助。 最初的问题是关于在打字稿中实现工厂模式(使用 AngularJS),并解决编译器错误。它没有说明生成动态生成的类。 @Martin 这个问题字面上只包含一个动态类的例子。 @MarcJ.Schmidt 是的,那是因为 ES6 是一种动态语言,问题是如何在 TypeScript 中做到这一点——它添加了类型签名。【参考方案2】:您是否正在寻找从函数返回的类类型?下面是一段代码 sn-p 我们如何在 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());
【讨论】:
【参考方案3】:我正在为同样的错误而苦苦挣扎。我的解决方案是删除
"declaration": true
来自tsconfig.json
或将其设置为false
。
【讨论】:
【参考方案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
;
【讨论】:
好答案!现在它甚至可以使用声明:true! :) 但是,您的最终建议正是我在开始时所做的尝试 - 这不起作用:类型 'typeof Foo' 不可分配给类型 'IFoo'。 @MiB 我想说,这是另一个问题。检查这个操场example ...显示这样的问题..如果IFoo
作为接口需要一些东西..Foo
没有实现......在那个例子中IFoo x:boolean
需要x 但是类没有它class Foo implements IFoo
希望它有点帮助
我想这是真的,但在我的情况下,将 public x: boolean = false;
添加到 class Foo
仍然会导致相同的错误。检查this【参考方案5】:
我认为这是一个正确的方法:
export let factory = () =>
class Foo /* ... */
return Foo as (new () => [key in keyof Foo]: Foo[key] )
;
Check it out on playground
【讨论】:
【参考方案6】:我发现separately provided solution 很满意:
export class MyClass
...
export type MyClassRef = new (...args: any) => MyClass;
鉴于该签名,我可以使用 MyClassRef
作为一种返回值:
exposeMyClass(): MyClassRef
return MyClass;
【讨论】:
【参考方案7】:旧问题的最新答案:
您需要在工厂方法之外定义类并使用'typeof'定义返回值。
class Foo
export const factory = (): typeof Foo =>
return Foo;
;
【讨论】:
为什么这不是公认的答案?谢谢@Niels Steenbeek 有时factory
接受用于定义类的参数,在这种情况下这是行不通的。以上是关于如何从 TypeScript 函数返回一个类?的主要内容,如果未能解决你的问题,请参考以下文章