8

フロントエンド/バックエンド データ構造間の単純なマッピングを作成しています。そのために、次のようなデコレータを作成しました。

function ApiField(
    apiKey: string,
    setFn: (any) => any = (ret) => ret,
    getFn: (any) => any = (ret) => ret
) {
    return function (target: AbstractModel, propertyKey: string) {
        target.apiFieldsBag = target.apiFieldsBag || {};
        _.assign(
            target.apiFieldsBag,
            {
                [propertyKey]: {
                    apiKey: apiKey,
                    setFn: setFn,
                    getFn: getFn
                }
            }
        );
    };
}

そして、これが私がそれを使用する方法です:

class AbstractCar {
    @ApiField('id')
    public id: string = undefined;
}

class BMW extends AbstractCar {
    @ApiField('cylinders')
    public cylinderCount: number;
}

class VW extends AbstractCar {
    @ApiField('yearCompanyFounded')
    public yearEstablished: number;
}

私が見ている問題は、実際のオブジェクトがデコレータに渡されるのではなく、常にそのプロトタイプであることです:

__decorate([
    ApiField('yearCompanyFounded')
], VW.prototype, "yearEstablished", void 0);

つまり、デコレーターでインスタンスに何かを割り当てると、常にプロトタイプにアタッチされます。これは、インスタンスのみを定義したいプロパティがおよびクラスVWでも使用できることを意味します(この例では、これはである)。これにより、2 つの異なるクラスに同じ名前で異なる API フィールドを持つ 2 つのプロパティを持つことができなくなります。AbstractCarBMWyearEstablished

この動作を回避する方法はありますか?

4

2 に答える 2

4

問題はpublic、クラス内は標準の JavaScript ではなく、TypeScript が行うことだけだということです。したがって、何をしても将来壊れる可能性があるため、注意する必要があります。

1 つの可能性は、Object.assign()インスタンス プロパティを追加するために使用することです (IINM はapiFieldsBag、オブジェクト リテラルによって作成されたオブジェクトから に転送する必要がありますthis)。

class AbstractCar {
    constructor() {
        Object.assign(this, {
            @ApiField('id')
            id: undefined,
        });
    }
}
于 2015-11-25T12:10:01.193 に答える