0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypeScript: オブジェクトから動的に別オブジェクトを生成する

Posted at

背景

DynamoDB の更新式を動的に作りたい、という目的からまずは

  • 引数から動的オブジェクトの生成を

という課題を解決することに

結論

作成例
import _, { keyBy } from "lodash";

const createUpdatingFormula = async (content: any) => {
    let mergeData = {};
    Object.keys(content).forEach((k) => {
        if (typeof content[k] == "object") {
            // 再帰処理へ
        } else {
            console.log("k", k);
            let keyName = `#${k}`;
            mergeData = _.merge(mergeData, {
                ExpressionAttributeNames: {
                    [`#${k}`]: k
                },
                ExpressionAttributeValues: {
                    [`:${k}`]: content[k]
                }
            });
        }
    })
    console.log(mergeData);
}
const item = {
    age: 33, name: "hoge", items: {
        Key: "hoge",
        Value: 15,
    }
};
createUpdatingFormula(item);

結果はこんな感じ

結果例
{
  ExpressionAttributeNames: { '#age': 'age', '#name': 'name' },
  ExpressionAttributeValues: { ':age': 33, ':name': 'hoge' }
}

説明

Object.keys/entries

これを使って、オブジェクトのキーを取得して作成していく
オブジェクトが内部にある場合は、typeof で型取得をして再帰するしかなさそう・・(とりあえず今はパス

Object.keys でキー一覧
[ 'age', 'name', 'items' ]
Object.entries で要素一覧
[
  [ 'age', 33 ],
  [ 'name', 'hoge' ],
  [ 'items', { Key: 'hoge', Value: 15 } ]
]

computed property で、プロパティを動的定義

"#column" や ":column" という名称でのプロパティ定義は、これを使って定義していく

更新式の動的定義
ExpressionAttributeNames: {
    [`#${k}`]: k
},

_.merge() で、結合

存在しているプロパティをすべて結合していけば完了

結合
mergeData = _.merge(mergeData, {
    ExpressionAttributeNames: {
        [`#${k}`]: k
    },
    ExpressionAttributeValues: {
        [`:${k}`]: content[k]
    }
});

失敗の記録

TypescriptParser は静的解析

当初、オブジェクト解析と考えて、TypescriptParser を試行したら・・
Class等の静的解析用だった・・。いつか使うこともあるだろう、Roslyn みたいに・・

parser
const parser = new TypescriptParser();
const parsedCode = await parser.parseFile('./lib.ts', '');

const parsedSource = await parser.parseSource(`class Person {
    // クラスの型宣言
    name: string
    age: number
    // constructorの引数に型宣言
    constructor(name: string, age: number) {
      this.name = name
      this.age = age
    }
  }
  `);
 console.log(parsedSource);

parseFile の第二引数は、内部で、path.relative() で第一引数を補完している

あとがき

再帰処理も頑張るか・・・どうか・・
まずは必要かを検討してこよう

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?