第2回 TypeScript という言語
TypeScript & 関数型講座
今講座のコンセプト
これから TypeScript を使う人には
実践を想定した TypeScript の重要な機能を学習できるように
今 JavaScript, Java, Scala を使っている人には
それらと比較して TypeScript がどのような言語なのかを知ってもらえるように
TypeScript の概要
● TypeScript はマイクロソフトによって開発され、メンテナンスされているフリーで
オープンソースのプログラミング言語
● TypeScript は JavaScript に対して、省略も可能な静的型付けとクラスベースオ
ブジェクト指向を加えた厳密なスーパーセットとなっている(いわゆる AltJS)
● つまり、型定義できる JavaScript
TypeScript の言語仕様
ただ一つの値のみとる型
他の言語ではあまり見られない(と思ったけど、Scala3 に入る予定)
リテラル型
const a = 100 // 100
const b = 'a' // a
const c = true // true
const d: 101 = 100 // 型 '100' を型 '101' に割り当てることはできません。
関数の型
// TypeScript
const test:(a: number, b: number) => number = (a, b) => a + b
// Scala
val test: (Int, Int) => Int = (a, b) => a + b
// Java
BiFunction<Integer, Integer, Integer> test = (a, b) -> a + b;
Java の関数は第一級オブジェクトではないが、関数型インターフェースというものを利
用して第一級オブジェクトっぽく見せている。
void 型
関数の返り値の型として使われ、「何も返さない」ことを表す
JavaScript では何も返さない関数は undefined となるため、void 型の値は
undefinde のみ。
function hello(): void {
console.log('hello')
}
Java でも同様に void が存在する。
Scala では Unit 型が大体同じことをしている。(厳密に void と Unit が同じなのかまで
は調べていない)
const a: any = 666 // any
const b: any = 'danger' // any
const c = a + b // any
any 型
プログラマの敗北
any を使うと TypeScript が持つ型の優位性が無くなり、ただの JavaScript と同じ振る
舞いになってしまう。そのため、やむをえない場合以外使うべきではない
型を無視するためのものなので、Java、Scalaにはない
プログラミングのスタイルの一種で、あるオブジェクトが特定のプロパティを持つことだ
けを重視し、その名前が何であるか(名前的型付け)は気にしない。一部の言語では
ダックタイピングと呼ばれている。
構造的型付け
class User {
constructor(public readonly name: string) {}
}
class Cat {
constructor(public readonly name: string) {}
}
const cat: Cat = new User('bob')
TypeScript で名前的型付け的なことをするには、ちょっとした工夫が必要。
構造的型付け
class User {
private readonly __nominal: void // private な要素を持たせることにより、他の構造と区別できる
constructor(public readonly name: string) {}
}
class Cat {
private readonly __nominal: void
constructor(public readonly name: string) {}
}
const cat: Cat = new User('bob')
// 型 'User' を型 'Cat' に割り当てることはできません。
// 複数の型に、プライベート プロパティ '__nominal' の異なる宣言が含まれています
型エイリアス
ある型を指し示す別名を宣言することができる
type User = {
name: string
}
class User2 {
constructor(public readonly name: string) {}
}
const a: User = new User2('bob') // 構造的型付けなので代入可能
型エイリアス
一応 Scala でも可能
type User = { def name: String }
case class User2(name: String) {}
val user: User = User2("bob")
Java には存在しない
interface
型エイリアスと同様に、構造に名前をつけるための方法。小さな差異がいくつかある
が、ほとんど型エイリアスと同じ。
interface User {
name: string
}
class User2 {
constructor(public readonly name: string) {}
}
const a: User = new User2('bob') // 構造的型付けなので代入可能
interface のメリット
定義と実装を分けることができ、プログラムを柔軟に保てる。
interface JournalRepository { getById: (id: number) => Journal }
class HttpJournalRepository implements JournalRepository {
getById(id: number): Journal { // サーバーからデータ取得 }
}
class InmemoryJournalRepository implements JournalRepository {
getById(id: number): Journal { // インメモリーでデータ取得 }
}
// 実装を切り替えても、プログラムの変更は必要ない
function getJournal(id: number, repository: JournalRepository): Journal {
return repository.getById(id)
}
interface VS class
interface は複数継承することが可能。そのため、一つのオブジェクトに複数の振る舞
いを持たせることができる。
複数の場所で型レベルの制約を強制するために使われるプレースホルダーの型。
ジェネリック型
class Some<T> {
constructor(public readonly value: T) {}
map<U>(f: (v: T) => U): Some<U> {
return new Some(f(this.value))
}
}
ジェネリック型パラメータに制限を加えられる
型境界
class A { private type = 'A' }
class B {}
class C extends A {}
class Some<T extends A> {
constructor(public readonly value: T) {}
}
const someB = new Some(new B())
// 型 'B' の引数を型 'A' のパラメーターに割り当てることはできません。
// プロパティ 'type' は型 'B' にありませんが、型 'A' では必須です。
const someC = new Some(new C())
配列のサブタイプで、固定長の配列を型付けするための型。
タプル型
const a: [string, boolean] = ['test', true]
const b: [string, boolean] = ['test', true, 1]
// 型 '[string, true, number]' を型 '[string, boolean]' に割り当てることはできません。
// ソースには 3 個の要素がありますが、ターゲットで使用できるのは 2 個のみです。
const c: [string, boolean] = ['test', 1]
// 型 'number' を型 'boolean' に割り当てることはできません。
Java にはない。
あくまで型を定義するのが面倒な場合の代替手段。多用は厳禁(Elm のようにタプル
の要素は 3 つまで、と要素数の制限を入れている言語もある)
合併型
A と B という 2 つのものがある場合、それらの合併(union)とは、それらの和(A, B, ま
たはその両方に含まれる全てのもの )を指す。
TypeScript では、型の合併を表現する特別な型演算子が用意されている。
type Cat = { name: string, purrs: boolean }
type Dog = { name: string, barks: boolean }
type CatOrDog = Cat | Dog
const test1: CatOrDog = { name: 'coco', purrs: true } // OK
const test2: CatOrDog = { name: 'boss', barks: true } // OK
const test3: CatOrDog = { name: 'boss', purrs: false, barks: true } // OK
const test4: CatOrDog = { name: 'boss' }
// 型 '{ name: string; }' を型 'CatOrDog' に割り当てることはできません。
// プロパティ 'barks' は型 '{ name: string; }' にありませんが、型 'Dog' では必須です。
合併型
こんなことも。
function test(value: string | number): null | number {
if (typeof value === 'number') {
return 10
} else {
return null
}
}
function test2(): void {
const result = test(1) // const result: number | null
result.toString() // NG Object is possibly 'null'.
}
合併型
Scala3 で取り入れられる予定。
Java には存在しない。
function test(a: number | string | boolean | null): void {
if (a == null) return console.log('null')
const b = a // const b: string | number | boolean
if (typeof a === 'number') return console.log('number')
const c = a // const c: string | boolean
if (typeof a === 'string') return console.log('string')
const d = a // const d: boolean
}
型の絞り込み
TypeScript はフローベースの型推論を行う。これにより、型の絞り込みを提供する。
trait 積木
case object 三角の積み木 extends 積木
case object 四角の積み木 extends 積木
case object 丸の積み木 extends 積木
trait Tree[T]
case class Leaf[T](value: T) extends Tree[T]
case class Branch[T](value: Seq[Tree[T]]) extends Tree[T]
タグ付き合併型
TypeScript で代数的データ型を表現する方法
代数的データ型とは、総体と、それを構成する構成子からなるデータ構造である
interface 三角の積み木 {
readonly type: '三角の積み木'
readonly a: string
}
interface 四角の積み木 {
readonly type: '四角の積み木'
readonly b: number
}
interface 丸の積み木 {
readonly type: '丸の積み木'
readonly c: boolean
}
type 積木 = 三角の積み木 | 四角の積み木 | 丸の積み木
タグ付き合併型
TypeScript では、文字列リテラルを用いた「タグ」というものを利用して表現する
// Not all code paths return a value.
function test(value: 積木) {
switch (value.type) {
case '三角の積み木':
return value.a // 型の絞り込みにより、三角のプロパティが使用できる
case '四角の積み木':
return value.b
}
}
タグ付き合併型
代数的データ型のメリットは、パターンマッチでの網羅チェックを行えることである。(要
出典)あと、再帰的データ構造を簡単に定義できる。
※ tsconfig.json で noImplicitReturns を true にする必要あり
交差型
A と B という 2 つのものがある場合、それらの交差(intersection)とは、それらの積
(A と B両方に含まれる全てのもの )を指す。
TypeScript では、型の交差を表現する特別な型演算子が用意されている。
type Cat = { name: string, purrs: boolean }
type Dog = { name: string, barks: boolean }
type CatAndDog = Cat & Dog
const test1: CatAndDog = { name: 'coco', purrs: true } // NG
const test2: CatAndDog = { name: 'boss', barks: true } // NG
const test3: CatAndDog = { name: 'boss', purrs: false, barks: true } // OK
const test4: CatAndDog = { name: 'boss' } // NG
function isNonEmpty<A>(
fa: ReadonlyArray<A>
): fa is ReadonlyNonEmptyArray<A> {
return fa.length > 0
}
function test(value: ReadonlyArray<string>) {
if (isNonEmpty(value)) {
const a = value // const a: ReadonlyNonEmptyArray<string>
}
}
ユーザー定義型ガード
引数を 1 つ取り、boolean を返す関数は、その引数の型を絞り込み可能にできる
readonly 修飾子
フィールドに初期値を割り当てた後でそのフィールドを変更できないことを宣言できる。
オブジェクトを不変にするために非常に重要。
const user: {
readonly name: string
} = {
name: 'bob'
}
user.name = 'alice' // 読み取り専用プロパティであるため、 'name' に代入することはできません。
オプション (?) 修飾子
TypeScript に、あるものが省略可能であることを伝える修飾子
function test(a?: number): number {
return a
}
// Type 'number | undefined' is not assignable to type 'number'.
// Type 'undefined' is not assignable to type 'number'
function test2(a?: number): number {
if (a === undefined) {
return 0
} else {
return a
}
}

More Related Content

PDF
「自分のとこでは動くけど…」を無くす devcontainer
PDF
概念モデルって難しいですよね
PDF
あなたのScalaを爆速にする7つの方法(日本語版)
PDF
12 分くらいで知るLuaVM
PDF
メルカリの開発スピードと品質を支える Selenium on Azure Kubernetes Service
PDF
超簡単!!なTestLinkの使い方
PDF
今さら聞けないDiとspring
PDF
Unityではじめるオープンワールド入門 アーティスト編
「自分のとこでは動くけど…」を無くす devcontainer
概念モデルって難しいですよね
あなたのScalaを爆速にする7つの方法(日本語版)
12 分くらいで知るLuaVM
メルカリの開発スピードと品質を支える Selenium on Azure Kubernetes Service
超簡単!!なTestLinkの使い方
今さら聞けないDiとspring
Unityではじめるオープンワールド入門 アーティスト編

What's hot (20)

PDF
Rust で RTOS を考える
PPTX
JavaScriptの仕組みと未来のJavaScript ~ESNextとは~
PDF
Scala警察のすすめ
PDF
ソーシャルゲームのためのデータベース設計
PDF
TypeScript & 関数型講座 第3回 関数型入門
PDF
トリコの動かし方
PDF
新人研修資料 向き合うエンジニア
PDF
BigQueryの課金、節約しませんか
PDF
『ラブライブ!スクールアイドルフェスティバル ALL STARS』を支えるビルドパイプライン 〜より安定したサービス提供を目指して〜
PDF
大企業アジャイルの勘所 #devlovex #devlovexd
PDF
Entity Framework(Core)についての概要を学ぼう
PDF
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
PDF
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
PPTX
async/await のしくみ
PPTX
backlogsでもCI/CDする夢を見る
PDF
Multibranch pipelineでいろいろ学んだこと
PDF
スマホサービスにおける、UIデザインのノウハウと実例
PDF
テスト分析・設計を体感しよう ~マインドマップを活用してテスト観点を発想しよう
PDF
リアクティブプログラミング
PDF
Rust Error Handling
Rust で RTOS を考える
JavaScriptの仕組みと未来のJavaScript ~ESNextとは~
Scala警察のすすめ
ソーシャルゲームのためのデータベース設計
TypeScript & 関数型講座 第3回 関数型入門
トリコの動かし方
新人研修資料 向き合うエンジニア
BigQueryの課金、節約しませんか
『ラブライブ!スクールアイドルフェスティバル ALL STARS』を支えるビルドパイプライン 〜より安定したサービス提供を目指して〜
大企業アジャイルの勘所 #devlovex #devlovexd
Entity Framework(Core)についての概要を学ぼう
Swagger ではない OpenAPI Specification 3.0 による API サーバー開発
サーバー知識不要!のゲームサーバー "Azure PlayFab" で長期運営タイトルを作ろう
async/await のしくみ
backlogsでもCI/CDする夢を見る
Multibranch pipelineでいろいろ学んだこと
スマホサービスにおける、UIデザインのノウハウと実例
テスト分析・設計を体感しよう ~マインドマップを活用してテスト観点を発想しよう
リアクティブプログラミング
Rust Error Handling
Ad

Similar to TypeScript & 関数型講座 第2回 TypeScript という言語 (20)

PDF
TypeScript 1.0 オーバービュー
PDF
TypeScript 言語処理系ことはじめ
PDF
Kotlin勉強会 in ehime
PDF
20120422i phonedeveloperworkshoppublished
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
PDF
きつねさんでもわかるLlvm読書会 第2回
PDF
Pfi Seminar 2010 1 7
PDF
JavaScript経験者のためのGo言語入門
PPTX
PDF
Python standard 2022 Spring
PDF
今から始める Lens/Prism
PDF
Kotlin Meets Data-Oriented Programming: Kotlinで実践する「データ指向プログラミング」
PDF
とあるFlashの自動生成
PDF
C++ lecture-0
PDF
Ruby test double
PPTX
T69 c++cli ネイティブライブラリラッピング入門
PDF
Boost.Flyweight
PDF
Essential Scala 第5章 シーケンス処理
PDF
Elasticsearchプラグインの作り方
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
TypeScript 1.0 オーバービュー
TypeScript 言語処理系ことはじめ
Kotlin勉強会 in ehime
20120422i phonedeveloperworkshoppublished
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
きつねさんでもわかるLlvm読書会 第2回
Pfi Seminar 2010 1 7
JavaScript経験者のためのGo言語入門
Python standard 2022 Spring
今から始める Lens/Prism
Kotlin Meets Data-Oriented Programming: Kotlinで実践する「データ指向プログラミング」
とあるFlashの自動生成
C++ lecture-0
Ruby test double
T69 c++cli ネイティブライブラリラッピング入門
Boost.Flyweight
Essential Scala 第5章 シーケンス処理
Elasticsearchプラグインの作り方
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
Ad

TypeScript & 関数型講座 第2回 TypeScript という言語