TypeScript入門の導入スライド
TypeScript入門 - 型は何を守るのか
TypeScriptで開発できるプログラム
Webアプリケーション、フロントエンド、サーバーサイドまで、型が付いた安全なコードを書けます。
1 / 5
TypeScript入門 - 型は何を守るのか
動くのに、間違っているコード
length を lenght と打ち間違えても、JavaScript はエラーにしません。存在しないプロパティを読んで undefined を返し、そのまま実行が進みます。
気付くのは、実行して画面を見たときだけです。
lenght と書いても止まりません。実行できてしまうのが厄介なところです。
const works = ["プロフィールサイト", "自己紹介カード"];
console.log("公開作品は" + works.lenght + "件です");
// 公開作品はundefined件です2 / 5
TypeScript入門 - 型は何を守るのか
同じ間違いを TypeScript で書く
言語を切り替えて、同じ lenght がどちらで止まるかを確かめます。
- TypeScript ではコード枠が赤くなる
- 実行する前に、エディタの中でエラーが出る
3 / 5
考えてみよう外しても進めます
TypeScript で works.lenght と書くと、いつエラーに気付きますか。
選ぶと、この枚の中で答えと理由を確かめられます。
4 / 5
TypeScript入門 - 型は何を守るのか
型は約束をコンピュータに見張らせるしくみ
works は文字列の配列だ、workCount は数値だ、と先に宣言しておくと、その約束を破ったところでエラーが出ます。人間のレビューでは見落とす打ち間違いを、機械が毎回同じ精度で拾います。
次のレッスンから、この約束の書き方を学びます。
5 / 5
TypeScript入門 - TypeScriptとJavaScript
TypeScriptで開発できるプログラム
Webアプリケーション、フロントエンド、サーバーサイドまで、JavaScript が動く場所ならどこでも使えます。
1 / 4
TypeScript入門 - TypeScriptとJavaScript
型の記法だけを足したもの
TypeScript は JavaScript を置き換える別の言語ではありません。今まで書いてきた const も配列も関数も、書き方を覚え直さずそのまま使えます。
ブラウザや Node.js が実行できるのは JavaScript だけ、という制約は残ります。
これは JavaScript としても TypeScript としても、そのまま正しく動きます。
const works = ["プロフィールサイト", "自己紹介カード"];
const count = works.length;
console.log(count);2 / 4
TypeScript入門 - TypeScriptとJavaScript
tsc が2つのことをする
書いたコードと、tsc が出力したコードを切り替えて見比べます。
- 型注釈は検査されたあとに消える
- 実行時には1バイトも残らない
3 / 4
拡張子を変えた1枚から、TypeScript は始まる
ファイルの拡張子を .js から .ts に変えたら、そこはもう TypeScript の世界です。中身を書き換えなくても、その瞬間から tsc が型の目で見はじめます。既存プロジェクトへの導入もファイル1枚ずつ .ts にしていけるので、一気に書き換える必要はありません。
4 / 4
名前の後ろにコロンと型名
型注釈は、変数名の後ろに型を書き添えるだけです。string が文字列、number が数値、boolean が true と false を表します。
プロフィールサイト
3件・公開中
型チェック 通過
: string文字列: number数値: boolean真偽値約束を破ると、その行でエラーになります。
1 / 3
TypeScript入門 - はじめての型注釈
引数に型が無いと、間違いが素通りする
型注釈のあり/なしを切り替えて、間違った呼び出しがどうなるか確かめます。
- 型が無いと "3" が数のふりをして通ってしまう
- 型があると、呼び出す側の間違いがそこで止まる
2 / 3
考えてみよう外しても進めます
関数の引数に型注釈を書かないと、このコースの設定ではどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 3
TypeScript入門 - 型推論
書かなくても型は付いている
注釈を書いていない変数にも、TypeScript は代入された値を見て型を決めています。これを型推論と呼びます。推論された型も、注釈で書いた型と同じ強さで働きます。
書いていないのに守られている、というのが TypeScript の気持ちよさの半分です。
workName に注釈は無いのに、lenght の打ち間違いがちゃんと捕まっています。
const workName = "プロフィールサイト";
const length = workName.lenght;
// エラー lenght は string にありません1 / 3
TypeScript入門 - 型推論
ホバーで推論結果を読む
対象を切り替えて、それぞれの行に何の型が付いているか確かめます。
- works は string[]
- count は works.length から number
- first は配列の要素なので string
2 / 3
TypeScript入門 - 型推論
どこまで書くか
目安は次のとおりです。関数の引数には書きます。外に公開する関数の戻り値には書きます。変数への代入は、推論に任せます。
型注釈は多いほど良いものではなく、推論できないところと、約束として残したいところに置くものです。
| 書く場所 | 理由 |
|---|---|
| 関数の引数 | 呼び出す側の間違いを止めるため |
| 公開する関数の戻り値 | 中身を直したときの事故を、その場で止めるため |
| 変数への代入 | 推論できるので、書いても情報が増えない |
3 / 3
string / number / boolean の3つ
TypeScript でいちばんよく使う型は string、number、boolean の3つです。プロフィールのデータは、たいていこの3つで書けます。
: string文字列: number数値: boolean真偽値型を取り違えると、実行は通るのに答えだけがおかしくなります。
1 / 3
TypeScript入門 - プリミティブ型
+ の意味は型の組み合わせで決まる
b の型を切り替えて、+ が足し算になるか連結になるか確かめます。
- 両方 number なら足し算
- 片方でも string が混ざると連結
2 / 3
考えてみよう外しても進めます
const a: number = 3; const b: string = "3"; a + b の結果は?
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 3
要素の型の後ろに [] を付ける
配列の型は、中に入る要素の型のうしろに [] を付けて書きます。配列そのものの型ではなく、中身の型を宣言している点が大事です。
string[]文字列の配列number[]数値の配列違う型を混ぜようとした行が、その場でエラーになります。
1 / 3
TypeScript入門 - 配列の型
push しようとする値をゲートが見る
push する値を切り替えて、配列まで届くか跳ね返るか確かめます。
- 要素の型と合えば通過
- 合わなければ入れる瞬間に止まる
2 / 3
取り出した要素にも型が付く
配列に型を付けると、そこから取り出した1個にも型が付きます。エディタが文字列用のメソッドだけを候補に出してくれるのが、一番のごほうびです。
使える (string のメソッド)
titles[0].toUpperCase()エラー (string に無いメソッド)
titles[0].toFixed(1)実務では Array<string> より短い string[] がよく使われます。
3 / 3
中カッコの中に形をそのまま書く
オブジェクトの型は、中カッコの中にプロパティ名と型を並べて書きます。値の形をそのまま写し取るような書き方です。
name: string名前の型workCount: number件数の型抜けと入れすぎの両方が、その場で指摘されます。
1 / 3
TypeScript入門 - オブジェクトの型
宣言した形と実際の値を線で結ぶ
実際の値を切り替えて、プロパティが対応しているか確かめます。
- 対応する行があれば線がつながる
- 無ければその場でエラーになる
2 / 3
考えてみよう外しても進めます
{ name: string; workCount: number } な引数に workCount を渡さずに呼ぶと?
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 3
TypeScript入門 - anyの危険
any は検査を止めるスイッチ
any は「どんな型でもよい」を表す型です。書いた瞬間、その値に対する検査がすべて止まります。
しかも any は周りに伝染します。型を付けた変数まで壊れが届きます。
any は書いたときは楽ですが、実行してはじめて落ちます。
const value: any = "プロフィールサイト";
value.toFixed(0);
// エラーにならない (実行時に落ちる)1 / 3
TypeScript入門 - anyの危険
any はゲートを素通りする
value の型を切り替えて、number 型の変数まで届くか確かめます。
- any にはゲートが無い
- unknown は確かめるまで止まる
2 / 3
分からない値には unknown を使う
本当に型が分からないときは any ではなく unknown を使います。typeof で確かめたブロックの中でだけ、その型として扱えます。
any
検査を止める。最後の手段
unknown
確かめるまで待たせる。基本はこちら
確かめれば使える、というのが unknown の強さです。
3 / 3
TypeScript入門 - nullと型
無いかもしれない値を型にする
ニックネームのように、入っているかもしれないし空かもしれない項目は string だけでは表せません。縦棒でつないで string | null と書きます。
確かめずに使おうとした行が、その場で止まります。
実行時に落ちる場所を、書いている最中に教えてくれています。
function label(
nickname: string | null
): string {
return nickname.trim();
// エラー 'nickname' is possibly 'null'.
}1 / 3
TypeScript入門 - nullと型
チェックを通った先だけが trim() に届く
コードを切り替えて、分岐を経由するかしないかを確かめます。
- チェック無し: 直行してエラー
- チェックあり: 両方のルートが通る
2 / 3
考えてみよう外しても進めます
null チェックを書かずに nickname.trim() と書くと?
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 3
type で型に名前を付ける
同じ形を何度も書くのは面倒です。type を使うと、型そのものに名前を付けて使い回せます。
type Profileここで名前を付けるprofile: Profileここで使うtype で書いたものは、コンパイルすると跡形もなく消えます。
1 / 3
TypeScript入門 - 型エイリアス
書き写しか、1か所からの配布か
書き方を切り替えて、直す場所がいくつになるか確かめます。
- 毎回書く: 3か所に同じ形が散らばる
- type で名前を付ける: 1か所を直せば全部に効く
2 / 3
TypeScript入門 - 型エイリアス
名前は部品として組み合わせられる
作った名前は、別の型の中でそのまま部品として使えます。データの形が変わったとき、直すのは type を書いた1か所だけになります。
10か所に書き写していたら、10か所すべてを直すことになっていました。
type Nickname = string | null;
type Profile = {
name: string;
nickname: Nickname;
};3 / 3
TypeScript入門 - 引数と戻り値の型
関数には入口と出口がある
入口が引数、出口が戻り値です。TypeScript ではその両方に型を書けます。この1行だけで、数値を2つ受け取って数値を返す関数だと宣言したことになります。
戻り値の型は書かなくても推論されますが、書くと自分の中身を自分で検査できます。
引数は名前の後ろ、戻り値は丸カッコの後ろに型を書きます。
function priceWithTax(
price: number,
taxRate: number
): number {
return Math.round(
price * (1 + taxRate)
);
}1 / 3
TypeScript入門 - 引数と戻り値の型
角括弧で囲んだ型が、中身を検査する
return の中身を切り替えて、型と食い違うとどうなるか確かめます。
- 中身が型と合えばそのまま通る
- 食い違うと、その場でエラーになる
2 / 3
考えてみよう外しても進めます
戻り値の型が : number の関数で return "" + total; と書くと?
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 3
TypeScript入門 - 省略できる引数
名前の後ろにハテナ
渡しても渡さなくてもよい引数は、名前の後ろに ? を付けて作ります。付けた引数は、渡さずに呼んでもエラーになりません。
省略できる引数は、必ず必須の引数より後ろに並べます。
? を付けなければ、渡し忘れはその場でエラーになります。
function greetVisitor(
name: string,
title?: string
): string {
return name + "さん、ようこそ";
}
greetVisitor("ゆめさく");
greetVisitor("ゆめさく", "エンジニア");1 / 5
TypeScript入門 - 省略できる引数
省略した引数の中身
title?: string と書いたとき、関数の中での title は文字列だけではありません。文字列か、渡されなかったことを表す undefined です。
確かめた後の分岐の中では、title は文字列として扱えます。
使う前に、渡されたかどうかを確かめます。
function greetVisitor(
name: string,
title?: string
): string {
return name + title.toUpperCase();
}
// エラー title is possibly undefined2 / 5
TypeScript入門 - 省略できる引数
呼び出しと確認を変える
渡す引数の数と、確かめる行の有無を別々に切り替えます。
- 呼び出しは引数1つと引数2つで切り替えられる
- 関数の中は確かめてから使うとそのまま使うで切り替えられる
- 渡さずにそのまま使うと、その行で止まる
3 / 5
考えてみよう外しても進めます
省略できる引数は、必須の引数より前に置けますか。
選ぶと、この枚の中で答えと理由を確かめられます。
4 / 5
ハテナは書く手間を減らす記号ではなく、決め忘れを封じる記号
省略できる引数を作ると、渡されなかったとき何を返すかを必ず決めることになります。
5 / 5
TypeScript入門 - デフォルト値と型
既定値を先に書く
引数のうしろにイコールで値を書くと、渡されなかったときにその値が使われます。呼ぶ側は limit を省略できます。
既定値そのものが、型のヒントにもなります。
イコールの右に書いた値が、渡されなかったときの既定値になります。
function listTopWorks(
titles: string[],
limit = 3
): string {
return titles.slice(0, limit)
.join(" / ");
}
listTopWorks(works);
listTopWorks(works, 2);1 / 5
TypeScript入門 - デフォルト値と型
既定値が型になる
2つめの引数の渡し方を変えて、limit と返る件数を見ます。
- 省略すると、既定値の3がそのまま limit に入る
- 既定値の3から、limit の型は数値だと決まる
- 文字列を渡すと、その行で止まる
2 / 5
考えてみよう外しても進めます
既定値が 3 の limit に、文字列の 2 を渡すとどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 5
ハテナとの違い
? を付けた引数は、関数の中で undefined かもしれない値になります。既定値はそうなりません。
? を付ける
function a(limit?: number) {
return limit * 2;
}
// エラー possibly undefined既定値を書く
function b(limit = 3) {
return limit * 2;
}
// これは通る渡されなければ既定値が入るので、中では最初から数値です。
4 / 5
決まった値があるなら既定値、無いこと自体が意味ならハテナ
無かったときの値がはっきり決まっているなら既定値、無いこと自体に意味があるならハテナです。
5 / 5
戻り値が無い関数の型
画面に出す、記録に残す、といった仕事だけをして終わる関数もあります。そういう関数の戻り値の型が void です。
: void戻り値なし1 / 5
宣言と中身が食い違う
返さない関数の戻り値に string と書いてしまうと、その場でエラーになります。
stringと書く
function logWork(
title: string
): string {
console.log(title);
}voidと書く
function logWork(
title: string
): void {
console.log(title);
}左は書いた時点でエラー、右が正しい void の形です。
2 / 5
TypeScript入門 - 戻り値のない関数
呼ぶ関数を切り替える
呼ぶ関数だけを入れ替えて、message に何が入るか見ます。
- void を返す logWork は、message に代入できない
- 文字列を返す runWorkLog なら、そのまま入る
3 / 5
考えてみよう外しても進めます
戻り値の型を void にした関数が正しく動いたか確かめたいときは、何を見ますか。
選ぶと、この枚の中で答えと理由を確かめられます。
4 / 5
TypeScript入門 - 戻り値のない関数
仕事の跡を外から見る
void の関数は値を返しませんが、仕事はしています。確かめたいときは、その関数が書き込んだ先を見ます。
記録が溜まっていくのは、関数の外から確かめます。
const workLogs: string[] = [];
function logWork(
title: string
): void {
workLogs.push("[log] " + title);
}5 / 5
関数そのものの型
これまでは引数と戻り値に別々に型を付けてきました。関数はまとめて1つの型としても書けます。矢印の左が引数、右が戻り値です。
1 / 5
変数の側に書く
関数型が効くのは、関数を変数に入れるときです。変数の側に型を書くと、右のアロー関数には型を書かなくて済みます。
title: string引数の型=> string戻り値の型2 / 5
TypeScript入門 - アロー関数の型
書く場所を見比べる
見る部分を切り替えて、2つの書き方で型がどこにあるか見ます。
- 引数の型は、どちらの書き方でも同じ場所にある
- 戻り値の型だけ、書く場所が矢印の右と丸かっこの後ろで変わる
- 合わない関数を入れると、その行で止まる
3 / 5
考えてみよう外しても進めます
変数の側に関数型を書いたとき、右のアロー関数の引数に型は必要ですか。
選ぶと、この枚の中で答えと理由を確かめられます。
4 / 5
TypeScript入門 - アロー関数の型
左と右のどちらに書くか
同じ形の関数を何度も入れ替える場所では変数の側、1回きりの定義なら関数の側、と考えると迷いません。
変数の側に書くと、名前のとなりで何が入るか読めます。
| 書く場所 | 向いている場面 |
|---|---|
| 変数の側 | 同じ形の関数を何度も入れ替える場所 |
| 関数の側 | 1回きりの定義 |
5 / 5
TypeScript入門 - コールバックの型
関数を受け取る関数
filter や map は関数を引数として受け取ります。渡す側の titles が string[] だと分かっているので、コールバックの引数の型は書かなくても決まります。
渡される側の関数をコールバック、受け取る側を高階関数と呼びます。
title に型を書いていないのに、文脈から string だと決まっています。
titles.filter((title) => title.length <= 8);1 / 5
TypeScript入門 - コールバックの型
求められる形は決まっている
filter が求めるコールバックは、文字列を受け取って真偽値を返す形です。真偽値を返さない関数を渡すと、その場で止まります。
number は boolean に代入できません、で止まります。
filter((title) => title.length);
// filter が求める形
// (item: string) => boolean2 / 5
TypeScript入門 - コールバックの型
渡す関数を入れ替える
filter に渡す関数を入れ替えて、受け口と合うか見ます。
- 求める形と渡す形で、戻り値だけを見比べる
- 戻り値の型がずれると、その行で止まる
3 / 5
考えてみよう外しても進めます
文字列を返す withBullet を filter に渡すとどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
4 / 5
TypeScript入門 - コールバックの型
切り出すと自分で書く
コールバックを名前付きの関数として外へ出すと文脈が無くなるので、引数と戻り値の型は自分で書きます。
型を書いておくと、filter に渡してよい関数かどうかがその行で分かります。
function isShort(title: string): boolean {
return title.length <= 8;
}5 / 5
