type FirstName = "John" | "Paul"
type LastName = "Lennon" | "McCartney"
// ユニオン型にすると、全通りの名前がUserNameに代入される
// John-Lennon | John-McCartney...
type UserName = `${FirstName}-${LastName}`
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!")
}
}
// この関数がデコレータファクトリ
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!")
}
}
<!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>