web-dev-qa-db-ja.com

TypeScript関数からクラスを返すにはどうすればよいですか?

Angular 1-基本的に:依存関係を引数としてファクトリを登録すると同様に機能する依存関係注入ライブラリでTypeScriptを使用しています。

これは、ES6でクラスを登録する方法です。

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

TypeScriptで同じことを書いた場合:

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

エラーでコンパイルに失敗する

エラーTS4025:エクスポートされた変数 'factory'はプライベート名 'Foo'を持っているか、使用しています。

TypeScriptがファクトリ関数からクラスを返すことができるようにする方法はありますか?

14
RiggerTheGeek

素早い回答

これを変える:

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

それに:

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

より長い答え

このエラーは、tsconfig.json設定によってトリガー/強制される可能性があります。

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

しかし、それは理由ではありません。それは単なるトリガーです。本当の理由(ここで説明するように クラスを返す関数をエクスポートするときのエラー:エクスポートされた変数がプライベート名を持っている、または使用している )は、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
};

Fooclassがエクスポートされるため、このアプローチは機能します外の世界へ。

私たちのケースに戻ります。 私たちはに戻したいにしたい =)エクスポートされません。そして、TSコンパイラが戻り値の型を決定するのを助ける必要があります。

明示的なものにすることができます:

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

しかし、さらに良いのは、いくつかのパブリックインターフェースを持つことです

export interface IFoo {}

そして、return typeのようなインターフェースを使用します:

export let factory = () : IFoo => {
    return class Foo implements IFoo {}
};
9
Radim Köhler

メソッドのコンシューマーがタイプにアクセスできるように、クラスもエクスポートする必要があります。

通常、ファクトリはクラスやコンストラクタではなくインスタンスを返します。

2
Martin

私は同じエラーで苦労していました。私のための解決策は、

"declaration": true

tsconfig.jsonから、またはfalseに設定します。

1
MiB

これは適切な方法だと思います。

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

遊び場で確認してください

0
Joseph Buchma