[TypeScript] 重要機能

### 名前空間
– exportで外部から使えるようにする

namespace myapp {
    namespace foundation {
        export interface printable {
            print():void
        }

        export interface stringable {
            getString():string
        }
    }

    export type Person = {
        name:string
        age:number
    }

    export class MyData implements
        foundation.printable,
        foundation.stringable {
            people:Person[] = []

            constructor(){}

            add(nm:string, ag:number){
                this.people.push({name:nm, age:ag})
            }

            print():void {
                console.log('*** mydata ***\n' + this.getString())
            }
            getString():string {
                let res = '[\n'
                for (let item of this.people){
                    res += ' "' +item.name+ ' (' + item.age + ')",\n'
                }
                return res + ']'
            }
        }
}

const mydata = new myapp.MyData()
mydata.add('taro', 39)
mydata.add('hanako', 28)
mydata.add('sachiko', 17)
mydata.add('jiro', 6)
mydata.print()

### モジュールとプログラムの分割
外部公開: export element
読み込み: import (element) from resources

src/lib.ts

export interface printable {
    print():void
}

export interface stringable {
    getString():string
}

export type Person = {
    name:string
    age:number
}

export class MyData implements printable, stringable {
        people:Person[] = []

        constructor(){}

        add(nm:string, ag:number){
            this.people.push({name:nm, age:ag})
        }

        print():void {
            console.log('*** mydata ***\n' + this.getString())
        }
        getString():string {
            let res = '[\n'
            for (let item of this.people){
                res += ' "' +item.name+ ' (' + item.age + ')",\n'
            }
            return res + ']'
        }
    }

index.ts

import { MyData } from './lib'

const mydata = new MyData()
mydata.add('taro', 39)
mydata.add('hanako', 28)
mydata.add('sachiko', 17)
mydata.add('jiro', 6)
mydata.print()

$ npm run build
$ node dist/main.js
*** mydata ***
[
“taro (39)”,
“hanako (28)”,
“sachiko (17)”,
“jiro (6)”,
]

### ミックスイン
複数のクラスを継承して機能を引き継ぐ

function applyMixins(derivedCtor: any, constructors: any[]){
    constructors.forEach((baseCtor) => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
            Object.defineProperty(
                derivedCtor.prototype,
                name,
                Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null)
            );
        });
    });
}

class Person {
    name:string = ''
    title:string = ''

    setPerson(nm:string, tt:string):void {
        this.name = nm
        this.title = tt
    }
}

class Pet {
    kind:string = ''
    age:number = 0

    setPet(k:string, ag:number):void {
        this.kind = k
        this.age = ag
    }
}

class Me {
    print():void {
        console.log(this.name + ' (' + this.age + ')\n'
            + '"' + this.title + '". pet is ' + this.kind + '!')
    }
}

interface Me extends Person, Pet {}
applyMixins(Me, [Person,Pet])

const me = new Me()
me.setPerson('taro', 'designer')
me.setPet('cat', 2)
me.print()

### 非同期処理とasync/await
実行したら後はどれがいつ終わるかわからない

function action(dt:number){
    return new Promise(resolve=>{
        setTimeout(()=> {
            console.log('fished promise!')
            resolve("delay:" + dt)
        }, dt)
    })
}

action(2000).then(res=>console.log(res))
action(1000).then(res=>console.log(res))
action(500).then(res=>console.log(res))

awaitは非同期でも処理が完了するまで待つ

async function doit(){
    let re1 = await action(2000)
    console.log(re1)
    let re2 = await action(1000)
    console.log(re2)
    let re3 = await action(500)
    console.log(re3)
}
doit()

### ネットワークアクセス
fetch().then(response=> hoge) と書く

function getData(url:string){
    fetch(url).then(res=>res.text()).then(re=>{
        console.log(re)
    })
}

const url = 'https://tuyano-dummy-data.firebaseio.com/message.json'
getData(url)

firebaseはCORSを解放しているが、解放していないサイトも多い

function getData(url:string){
    fetch(url).then(res=>res.json()).then(re=>{
        for (let item of re){
            console.log(item)
        }
    })
}

const url = 'https://tuyano-dummy-data.firebaseio.com/sample_data.json'
getData(url)

### ネットワークに同期アクセス
アクセスを非同期化する

async function getData(url:string){
    const response = await fetch(url)
    const result = await response.json()
    for(let item of result){
        console.log(JSON.stringify(item))
    }
}

const url = 'https://tuyano-dummy-data.firebaseio.com/sample_data.json'
getData(url)

### POST送信

async function getData(url:string, obj:object){
    await fetch(url, {
        method: 'POST',
        mode: 'cors',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(obj)
    })
    const response = await fetch(url)
    const result = await response.json()
    console.log(result)
}

const url = "https://tuyano-dummy-data.firebaseio.com/sample_data.json"

const obj = {
    title: 'hello!',
    message: 'This is sample message!'
}

getData(url, obj)

なるほど、TypescriptというよりJavaScriptでも重要なことやな