TypeScriptのstaticアクセス修飾子を使う時理解する4つの事

# TypeScriptのstaticアクセス修飾子を理解する4つの事

publicとprivateはなんとなくわかるのですが、たまーにstaticってどういう役割なんだっけなって(ちょっと恥ずかしいけど)なるので(protectはいいや)
この際意識の上に上げる。。

下記ようなコードを書きました。
Errorです

## やりたい事
「インスタンスメソッド経由でstaticメソッドを呼び出し別のstaticメンバの値を取得すること」

※このコードのどこが悪いかお気付きの方はさようなら。東京行っても頑張ってください。

[下記のコード](http://www.typescriptlang.org/Playground#src=class%20Faa%20%7B%0A%20%20%20%20static%20named%20%3A%20string%20%3D%20'eee'%3B%0A%20%20%20%20constructor(private%20name%3F%3A%20string)%7B%0A%20%20%20%20%7D%0A%20%20%20%20get%20getName()%20%3A%20string%7B%0A%20%20%20%20%20%20%20%20return%20this.name%0A%20%20%20%20%7D%0A%20%20%20%20set%20getName(name%3Astring)%7B%0A%20%20%20%20%20%20%20%20this.name%20%3D%20name%3B%0A%20%20%20%20%7D%0A%20%20%20%20static%20main()%7B%0A%20%20%20%20%20%20%20%20alert(Faa.named)%0A%20%20%20%20%7D%0A%7D%0AFaa.main()%2F%2Fok%20%2F%2Fe.g%0Avar%20h1%20%3D%20new%20Faa()%0Ah1.main()%2F%2FError):TypeScriptPlayground

```ts
class Faa {
	static named : string = 'eee';
	constructor(private name?: string){
	}
	get getName() : string{
		return this.name
	}
	set getName(name:string){
		this.name = name;
	}
	static main(){
		alert(Faa.named)
	}
}
Faa.main()//ok //e.g
var h1 = new Faa()
h1.main()//Error
//typescript compile Error →　property 'main' does not exist on type of Faa 
//consoleError　→ "h1.main is not a function" 
```
getter、setterとかはダミーです

## static
①クラスに紐づくメンバ(静的メンバ)
②アクセスは「Class名.メンバ名」。非static内からの呼び出す場合もこの記述
③static内からstaticなメンバにアクセスするには「this.メンバ名」
④静的メンバは型引数を参照できない

## staticだと何が嬉しいのか
・インスタンスを生成しなくても静的メソッドを実行できる(上のコードの「//ok //e.g」部分)
・同じクラスから生成されたインスタンスが静的メンバを共有できる(下で説明)



つまり僕はこうしなくてはいけなかったんです。
[下記のコード](http://www.typescriptlang.org/Playground#src=class%20Faa%20%7B%0A%20%20%20%20static%20named%20%3A%20string%20%3D%20'eee'%3B%0A%20%20%20%20constructor(private%20name%3F%3A%20string)%7B%0A%20%20%20%20%7D%0A%20%20%20%20get%20getName()%20%3A%20string%7B%0A%20%20%20%20%20%20%20%20return%20this.name%0A%20%20%20%20%7D%0A%20%20%20%20set%20getName(name%3Astring)%7B%0A%20%20%20%20%20%20%20%20this.name%20%3D%20name%3B%0A%20%20%20%20%7D%0A%20%20%20%20public%20main()%7B%2F%2F%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%8B%E3%82%89%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%99%0A%20%20%20%20%20%20%20%20Faa.main()%0A%20%20%20%20%7D%0A%20%20%20%20static%20main()%7B%0A%20%20%20%20%20%20%20%20alert(Faa.named)%0A%20%20%20%20%7D%0A%7D%0Avar%20h1%20%3D%20new%20Faa()%0Ah1.main()):TypeScriptPlayground

```ts
class Faa {
	static named : string = 'eee';
	constructor(private name?: string){
	}
	get getName() : string{
		return this.name
	}
	set getName(name:string){
		this.name = name;
	}
//追加/////////
	public main(){//インスタンスメソッド経由で呼び出す
		Faa.main()
	}
//////////////
	static main(){
		alert(Faa.named)
	}
}
var h1 = new Faa()
h1.main()
```

パブリックなインスタンスメンバを経由して静的メンバへアクセスする。
なんかget,setに似てる。。

生成されたJSをみると紐づくオブジェクトが違うね

```js
    Faa.prototype.main = function () {//public
        Faa.main();
    };
    Faa.main = function () {//static
        alert(Faa.named);
    };
```


## 「同じクラスから生成されたインスタンスが静的メンバを共有できる」ってなあに？

こうだよ
[下記のコード](http://www.typescriptlang.org/Playground#src=interface%20Iman%7B%0A%09giveManey()%3A%20number%3B%0A%7D%0Aclass%20Man%3CT%3E%20implements%20Iman%7B%0A%20%20%20%20static%20saifcontent%20%3Anumber%20%3D%200%3B%0A%20%20%20%20static%20giveManey%3CT%3E(maney%3Anumber)%7B%0A%20%20%20%20%20%20%20%20this.saifcontent%20%2B%3D%20maney%3B%0A%20%20%20%20%7D%0A%20%20%20%20public%20giveManey%3CT%3E()%7B%0A%20%20%20%20%20%20%20%20return%20Man.saifcontent%3B%0A%20%20%20%20%7D%0A%7D%0AMan.giveManey(1000)%3B%2F%2F1000%0Avar%20dd%20%3D%20new%20Man%3Cnumber%3E()%0Aconsole.log(dd.giveManey())%2F%2F%E5%88%A5%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%A7%E3%82%82%E3%81%93%E3%81%AE%E6%99%82%E7%82%B9%E3%81%A7static%E8%B2%A1%E5%B8%83%E3%82%92%E5%85%B1%E6%9C%89%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%80%821000%0AMan.giveManey(2000)%3B%2F%2F3000%0Avar%20cc%20%3D%20new%20Man()%3B%0Aconsole.log(cc.giveManey())%2F%2F%E5%88%A5%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%A7%E3%82%82%E3%81%93%E3%81%AE%E6%99%82%E7%82%B9%E3%81%A7static%E8%B2%A1%E5%B8%83%E3%82%92%E5%85%B1%E6%9C%89%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%A73000%0AMan.giveManey(500)%3B%2F%2F3500%0A%0Aalert(Man.saifcontent)%3B):TypeScriptPlayground

```ts
interface Iman{
	giveManey(): number;
}
class Man<T> implements Iman{
    static saifcontent :number = 0;
    static giveManey<T>(maney:number){
        this.saifcontent += maney;
    }
    public giveManey<T>(){
        return Man.saifcontent;
    }
}
Man.giveManey(1000);//1000
var dd = new Man<number>()
console.log(dd.giveManey())//別インスタンスでもこの時点でstatic財布を共有している。1000
Man.giveManey(2000);//3000
var cc = new Man();
console.log(cc.giveManey())//別インスタンスでもこの時点でstatic財布を共有しているので3000
Man.giveManey(500);//3500

alert(Man.saifcontent);
```

同じ親クラスから派生したインスタンスが変化する親クラスのstaticの値を共有していることがわかります。


## 「静的メンバは型引数を参照できない」ってなあに？

なるほど。。

```ts
class X<T>{
  static a:T;//static menbers cannot reference class type paramerters
}
```
staticなメンバーはclass型のパラメーターを参照できないってエラーでます。
staticにこういうことはやりませんよね。

## まとめ（TypeScriptのstaticアクセス修飾子を理解する4つの事）

①クラスに紐づくメンバ(静的メンバ)
②アクセスは「Class名.メンバ名」。非static内からの呼び出す場合もこの記述
③static内からstaticなメンバにアクセスするには「this.メンバ名」
④静的メンバは型引数を参照できない


## 最後に

staticをマヨつけて食べたい