💨

【TypeScript】クラスからプロパティを抜き出す関数作った

2023/10/16に公開

結論

export const getClassProperties = (obj: object): string[] => {
    const getOwnProperties = (obj: object) =>
        Object.entries(Object.getOwnPropertyDescriptors(obj))
            .filter(([name, {value}]) => typeof value !== 'function')
            .map(([name]) => name)
    const _getProperties = (o: object, properties: string[]): string[] =>
        o === Object.prototype ? properties : _getProperties(Object.getPrototypeOf(o), properties.concat(getOwnProperties(o)))
    return _getProperties(obj, [])
}

参考

以下の記事を参考にしました、というかほぼそのまんまです。
https://qiita.com/suin/items/b807769388c54c57a8be

「typeof value === 'function'」を「typeof value !== 'function'」に変更しただけです。

言い訳

そもそもそういう関数があるのかどうかもよくわからないし、参考記事様の処理も知らない関数出てきてヨクワカラナイ。
動けばいいのさ

事由

どうも、JavaScript派のたぬき教祖です。
最近Nuxt3に乗り換え、一部でTypeScriptを使い始めてます。
個人開発なので変なバグとかないし、JetBrainsのIDE使ってりゃJSでも型のチェックしてくれるので、型定義とか強制のTSはめんどいと思いつつ、私はプログラマ初期のころはC#が好きだったので、クラスが使いたくなってTSも触ってます。

で、今DBやアプリの設計とかをするツールを作ってます。
まだ全然途中で大したことできませんが
https://n-dev.vercel.app/

クラスって設計図じゃないか?

アプリ開発の中でいろんな設計しますが、私的にはDBが最強の設計図で、そこにclassがあるとほぼ全体を示す設計図になると思ってます。
class作るのも結構めんどいですが、だからclassは好きなんですよね。

でも今回DB関係のアプリを作ると、例えばこういうクラスができる

export class DbColumn {
    key: string = "";

    constructor() {
        this.key = getRandom(8, "string");
    }

    columnNameJP: string = "";
    columnName: string = "";
    columnLength: number | null = null;
    columnType: string = "";
    columnDefault: string = "";
    columnDefaultType: string | null = null;
    columnCollation: string | null = null;
    columnAttribute: string | null = null;
    columnNullable: boolean = false;
    columnIndex: string | null = null;
    columnUnique: boolean = false;
    columnGuiElement: string | null = null;
    columnComment: string = "";
    foreignTable: string | null = null;
    foreignColumn: string | null = null;
}

で、この「DbColumn」のインスタンスからCSVファイルとして出力する場合に以下のように書きたいわけですが、

for(let key of keys){
  csv += dbColumn[key] + ",";
}

// こうは書きたくない
// const keys = ["columnNameJP", "columnName", "columnType",,,,]

こんな風に2か所に定義したくないじゃないですか、正規化的に。
同じこと2回書くのも嫌だし、片方直すともう片方直さなきゃいけないのも嫌だ。
で、自動的にクラスからプロパティを抜き出そう、となったわけですね。

気になるのはクラスの定義からではなく、インスタンスからしかgetできないところかなあ。
あと、そのままkey使うと怒られるので、以下もご参考に。
https://qiita.com/Nossa/items/e01d0bce67b760c0bcb9

良い方法あったら教えてください。

ところで

記事によって色々なんですけど、TypeScriptってプロパティなの?メンバ変数なの?フィールドなの?keyなの?

Discussion