関数について
基本的な関数
// 名前付き関数 function add(x: number, y: number): number { return x + y; } // 無名関数 let myAdd = function(x: number, y: number): number { return x + y; };
関数の型
type FuncType = (x: number, y: number) => number; const func: FuncType = (x: number, y: number) : number => { return x + y; }; console.log(func(1, 2)); // 3 を出力
任意引数とデフォルト引数
const getVolume = (horizontal: number, vertical = 5, height?: number): number => { return horizontal * vertical * ((height) ? height : 1); } console.log(getVolume(10, 10, 10)); // 1000 を出力 console.log(getVolume(10, 10)); // 100 を出力 console.log(getVolume(10)); // 50 を出力
Rest引数(Rest Parameters)
function buildNames(...restOfName: string[]) { return "(" + restOfName.join(" ") + ")"; } console.log(buildNames("Baggio", "Zidane", "Totti", "Beckham")); // (Baggio Zidane Totti Beckham) を出力 console.log(buildNames()); // () を出力
必ず1件は指定させたいのであれば・・・
function buildNames(firstName: string, ...restOfName: string[]) { return "(" + firstName + " " + restOfName.join(" ") + ")"; }
thisとアロー関数
下記をブラウザで実行するとthisには deckオブジェクトではなくwindowが設定されてしまうためエラーとなる
let deck = { suits: ["hearts", "spades", "clubs", "diamonds"], cards: Array(52), createCardPicker: function() { return function() { let pickedCard = Math.floor(Math.random() * 52); let pickedSuit = Math.floor(pickedCard / 13); return {suit: this.suits[pickedSuit], card: (pickedCard % 13) + 1}; } } } let cardPicker = deck.createCardPicker(); let pickedCard = cardPicker(); console.log("card: " + pickedCard.card + " of " + pickedCard.suit);
アロー関数は、関数が実行された場所ではなく、関数が作られた場所でthisを捕捉する為、thisはdeckオブジェクトを参照するようになる。
let deck = { suits: ["hearts", "spades", "clubs", "diamonds"], cards: Array(52), createCardPicker: function() { // アロー関数に変更 return () => { let pickedCard = Math.floor(Math.random() * 52); let pickedSuit = Math.floor(pickedCard / 13); return {suit: this.suits[pickedSuit], card: (pickedCard % 13) + 1}; } } } let cardPicker = deck.createCardPicker(); let pickedCard = cardPicker(); console.log("card: " + pickedCard.card + " of " + pickedCard.suit);
thisパラメーター
ただ、上記の場合、--noImplicitThisフラグをコンパイラに渡している場合、this.suits[pickedSuit]のthisがany型であることが指摘されてしまうらしい。これを解消する為には次のthisパラメータを使用する。
noImplicitThis・・・thisの型が暗黙的にanyになる場合、エラーが出るようになる
function f(this: void) { // thisを明確にする為、第1引数にthisを指定する // この関数を呼び出す際にこの第1引数を指定することはない // もし関数に引数を渡したい場合は第2引数以降に定義する }
interface Card { suit: string; card: number; } interface Deck { suits: string[]; cards: number[]; createCardPicker(this: Deck): () => Card; } let deck: Deck = { suits: ["hearts", "spades", "clubs", "diamonds"], cards: Array(52), // NOTE: The function now explicitly specifies that its callee must be of type Deck createCardPicker: function(this: Deck) { return () => { let pickedCard = Math.floor(Math.random() * 52); let pickedSuit = Math.floor(pickedCard / 13); return {suit: this.suits[pickedSuit], card: (pickedCard % 13) + 1}; } } } // createCardPickerに引数を指定しなくてもコンパイルエラーにならない let cardPicker = deck.createCardPicker(); let pickedCard = cardPicker(); console.log("card: " + pickedCard.card + " of " + pickedCard.suit);