【Strapi】generateされたtsファイルのAttribute.Integerをnumberに変換する
こんにちは、フリーランスエンジニアの太田雅昭です。
以前に、strapiでgenerateされた型定義を他ライブラリで使い回す方法を書かせていただきました。
【Strapi】generated後のd.tsファイルをライブラリに再利用する
今回は、それ以降のお話です。
Attribute.Integerなどはそのまま使えない
generateされた型定義には、以下のような型があります。
Attribute.Integer
これをそのままnumberとして使えませんので、numberにする必要があります。順を追って書きます。
numberに変換する
ひとまず属性を整理する
まずは普通に継承してみます。
export type DbBidData = ApiBidBid["attributes"];
ところがこれだと、例えばid属性が無かったり、またcreatedAt,updatedAtなどが余分に含まれていたりします。これを間引くために以下のようにします。
export type DbBidData = Omit<ApiBidBid["attributes"], 'createdAt'|'updatedAt'|'createdBy'|'updatedBy'> & {
id? number,
createdAt?: any,
updatedAt?: any,
createdBy?: any,
updatedBy?: any,
}
これで、idがある可能性を含め、またcreatedAtなどは存在しない場合もあるとすることができました。
これでほぼ終わりなのですが、全てのContentTypesに毎回これを書くのは大変ですので、再利用できるようにします。
type Transform<T, K extends keyof T = never> = Omit<T, 'createdAt' | 'createdBy' | 'updatedAt' | 'updatedBy' | K> & {
id?: number,
createdAt?: any,
updatedAt?: any,
createdBy?: any,
updatedBy?: any,
};
export type DbBidData = Transform<ApiBidBid["attributes"]>
これで再利用できるようになりました。
Attribute.Integerをnumberに変える
続いてAttribute.Integerをnumberに変換します。以下のように変換用のコードを書きます。
type ConvertTypes<T> =
T extends Attribute.Relation ? Attribute.Relation | number :
T extends Attribute.Integer ? number :
T extends Attribute.String ? string :
T extends Attribute.Float ? number :
T;
type ConvertProperties<T> = {
[P in keyof T]: ConvertTypes<T[P]>;
};
これを使用して、以下のようにします。
type Transform<T, K extends keyof T = never> = Omit<ConvertProperties<T>, 'createdAt' | 'createdBy' | 'updatedAt' | 'updatedBy' | K> & {
id?: number,
createdAt?: any,
updatedAt?: any,
createdBy?: any,
updatedBy?: any,
};
export type DbBidData = Transform<ApiBidBid["attributes"]>
これで、汎用的に使えるtypeになりました。Strapiが自動でここまでやってくれると有難いのですが、このような使い方はマイナーなのでしょうか。
いっそ全てをオプショナルにする
データ一部更新時には、全てのフィールドを埋める必要はありません。そのような用途を考慮すると、以下のようにすべてをオプショナルにしてしまうてもあります。
type ConvertProperties<T> = {
[P in keyof T]?: ConvertTypes<T[P]>;
};
小話
作業中はずっと音楽を聴いているのですが、今でだいたい30時間分くらいのプレイリストになっています。もっと増やしたいのですが、いい音楽どこかに転がってないですかね。