less than 1 minute read

学んだこと

テンプレートリテラル型

type FirstName = "John" | "Paul"
type LastName = "Lennon" | "McCartney"

// ユニオン型にすると、全通りの名前がUserNameに代入される
// John-Lennon | John-McCartney...
type UserName = `${FirstName}-${LastName}`

デコレータを使って Class に関数を適用する方法

  • デコレータ
    • クラスをデコレーション
    • 既存のクラスやメソッドに追加機能をいれる事ができる
    • 定義時に実行される
function Logging(target: Function){
  console.log("Logging")
}

// @関数名を定義する
// デコレーションしたい所によって@を入れる箇所が異なる
// 今回はこのクラスをデコレーションしたいため、クラスの前に定義する。
@Logging
Class User{
  name = "Quill";
  constructor(){
    console.log("User was created!")
  }
}

デコレータファクトリを使用して、デコレータに引数を渡す方法

  • デコレータファクトリ
    • 設置したデコレータによって呼び出される式を返す関数
// この関数がデコレータファクトリ
function Logging(message: string){
  return function (constructor: Function){
    console.log(message)
  }
}

@Logging("LoggingUser")
Class User{
  name = "Quill";
  constructor(){
    console.log("User was created!")
  }
}

デコレータを使って簡易版フレームワークを作成する

  • html で h1 タグの文字列を表示する簡易的なフレームワークを作成してみる。
  • ts 側
// この関数がデコレータファクトリ
function Logging(message: string){
  return function (constructor: Function){
    console.log(message)
  }
}

// ここでフレームワークを作成
function Component(template: string, selector: string){
  // 新しくインスタンスを生成
  // templeteにはHTMLが格納されているため、innerHTMLにいれる
  // textContentにはインスタンスで生成したnameをそのまま渡す
  return function(constructor: { new(...args: any): {name: string} }){
    const mountedElement = document.querySelector(selector);
    const instance = new constructor();
    if(mountedElement){
      mountedElemet.innerHTML = templete;
      mountedElement.querySelector("h1")!.textContent = instance.name;
    }
  }
}

@Component("<h1></h1>", "#app")
@Logging("LoggingUser")
Class User{
  name = "Quill";
  constructor(){
    console.log("User was created!")
  }
}
  • html 側
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="dist/decorator.js" defer></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>