Typescript書き方の速成まとめ
目次
1. 概論・セットアップ
- transpile言語 (類似コンパイル言語)
- Javascriptと交換
- Typescriptの主な役目
- コンパイル時にタイプチェックを行うこと
Typescript setup & compile
1 | # 初期化 |
typescript online play
https://www.typescriptlang.org/play
2. tsconfig
http://json.schemastore.org/tsconfig
● Top Level Properties
1 | compileOptions ★ |
compileOptions : type
- TypeScript2からサポートするType Definition System関連オプション
- 何も設定しないと、自動で
./node_nodules/@types/*
をインポート- ex:
./node_nodules/@types/react/*
,./node_nodules/@types/babel__*/*
- ex:
- @typesは、コンパイル時のタイプチェックはもちろん、IDEのコードアシスト、シンタクスチェックなどでも使われる大事な定義ファイル
- typeRoots
- 設定すると、設定したパスだけインポート
- types
- 設定すると、配列内に指定したモジュール、または
./node_nodules/@types/
内のモジュール名から探す。 []
だと使わない
- 設定すると、配列内に指定したモジュール、または
- typeRootsはtypesは、どっちか一つだけ使う。
1 | "typeRoots": { |
compileOptions : target, lib
- target
- buildするバージョンを指定
- 指定しないと、基本esバージョン
- lib
- 基本type difinitionライブラリを指定
- 指定しないと、esバージョンに依存したライブラリを使用
- 指定すると、指定したライブラリのみを使う
1 | "target": { |
compileOptions : outDir, outFile
1 | "outDir": { |
compileOptions : module
- module
- compileされた結果物のモジュールシステムを指定
target
がes6だと、es6がデフォルトtarget
がes6じゃないとcommonjsがデフォルト
- moduleResolution
- tsソースで使用されるモジュールを指定
- CommonJSの場合
Node
、それ以外はだいたいClassic
- pathsと baseUrl
- 指定すると、該当パスのモジュールをロード
- 普通使わなくてOK。(細かいモジュール連携に必要)
- rootDirs
- ロードするモジュールのルートパス配列
- 普通使わなくてOK。(細かいモジュール連携に必要)
1 | "module": { |
3. TypeScript Basic Types
TypeScriptで定義した基本データタイプ
User Defined Typesも、基本データタイプからの拡張
superset (ECMAScript Standard)
- boolean, number, string, null, undefined
- array (object, non-primitive)
- symbol (ecma6)
- 固有で修正不可能なデータとしてアサイン
- primitive値を指定
Subtypes
- undefined & nullは、すべてのタイプに対してのサブタイプ
- すべてのタイプに、undefinedとnullはアサインできる。
- しかし、compileOptionで,
--strictNullChecks
を使うと、void
か、自分自身にだけアサインでできるようになる。
- その場合は、union typeで指定しなきゃいけない。
- ex :
let union: string | null | undefined = 'str'
Additional Type
- void
- タイプがない、空の概念
- 関数のリターンタイプくらいで使う(リターンする値がない時)
- any
- 何のタイプにもなれる
- Anyは非推奨、TypeScriptを使う意味が薄れる。
- compileOptionで、エラーになるように指定も可能(
noImplicitAny
)
- never
- 結果を返さないため、タイプを持たない。
- あんまり使うところがないが、関数のリターンタイプくらいで使う
- infinitely loop function
- absolutely throw Error
- absolutely return error(‘message’)
- enum
- 列挙型(他の言語と同じ)
- 複数の変数に対して、一連の定数値をアサイン
enum Color {Red, Green, Blue}; let c: Color = Color.Red; let colorName: string = Color[c];
- tuple (object, non-privitive)
- 複合タイプを持つ配列
let x: [string, number] =['hello', 10];
- 値を持って使うときに、どういうタイプかチェックしない限りわからないため、使うのに注意は必要
- Union Type
- タイプの共用体
let someVar: string | number | boolean = false
Type Assigned by literal
- Literal値で、タイプを定義するのも可能。指定したLiteralのみ設定可能
let someVar: "a" | 5 | false = 5
Generic
パートで記述するkeyof (Indexed Type Query)
演算子の理解とつながる。
4. var, let, const
VS var, let, const
- var
- ES5
- variable scope : function
- hoisting : O
- re-difinition : O
- let, const
- ES6
- variable scope : block
- hoisting : X
- re-difinitio : X
- varより、let, const推奨
- コード分析が直感的になる
- letとconstのタイプ推論
let a: string = "str"; //明示的string type
let b = "str"; //タイプ推論によるstring type
const c: string = "str"; //明示的string type
const d = "str"; //タイプ推論によるLiteral type
5. Type Assertion
- とある変数を参照する時、タイプを明示的に絞ること
- type castingとは違い、データを変換したりしない
- とある変数を、指定タイプであることを前提に使うという宣言
- もし使う場合があるなら、宣言に対しての信頼性が大事
- 使い方
- someVar as TYPE
- <TYPE>someVar (jsxと紛らわしいので、非推奨)
1 | // 主に曖昧なタイプから絞るときに使う。 |
6. Type Alias
特定のタイプに別称をつけて使うことができる。
あくまで、作られたタイプの参照を持つだけで、タイプを作ることではない。
1 | //alias to union type |
7. Interface
実装を持たず、ステート(プロパティ)とビヘイビアの形式の定義のみを記述した抽象データタイプ。
- インタフェースの抽象というのは、インスタンス化観点から抽象的であり具体を持たいないため、単体では実態を持てないという意味を内包している。
- 継承するクラスたちに対してのプロトコル(約束)の役目を果たす。
interface basics
1 | //interface |
interface - indexable type
indexのタイプとしては、stringか、numberを指定可能
1 | interface Person { |
1 | interface NumIndex { |
class implements interface
1 | interface IPerson { |
interface extends interface
1 | intrface Person { |
function with interface
1 | interface funcPerson { |
8. Class
オブジェクトの初期ステート(プロパティ)とビヘイビアを記述したテンプレートであり、User Defined Data Type.
class basics
1 | class Person { |
Abstract class
1 | abstract class APerson { |
readonly keyword & static keyword & private constructor
※ typescriptでは、anti-partternだという意見もあり
1 | class Logger { |
9. Generic
パラメータのデータタイプを、インスタンス化の後で明示するプログラミング手法(to-be-specified-later)
入力・出力のデータタイプを、任意のタイプに抽象化宣言する。
タイプチェックは、ランタイムの前にコンパイラでしてくれるが、内部動作メカニズムとしては、実際にどういうデータタイプで入力・出力されるかは、インスタンス化後、実際に呼び出されるときに確定される。
Generic basics
1 | function doPingPong<T>(message: T): T { |
Generic with class
1 | class Code<T extends string | number, O> { |
10. keyof -Lookup Types-
keyof
basics
- Indexed Type Lookup Query 演算子
- オブジェクトで、アクセスが許容されているプロパティのインデックスを
Literal Type
として算出する。 Generic
と一緒に使うと有用
1 | //-- indexed type query from Interface |
Generic with keyof
- ランタイム前に、間違ったプロパティアクセスなどが検出できる。
1 | function getProperty<T, K extends keyof T>(obj:T, key:K) { |
11. Iterator
今までの巡回
Array巡回
1 | // es3 |
Object巡回
1 | // -- for in |
example
1 | const array = ['first', 'second']; |
Symbol.iterator
概要
- プロパティ。巡回関数が具現されているとiterableなタイプになる。
- Array, Map, Set, String, Int32Array, Uint32Arrayなどには、内蔵された具現体があるので、iterableなタイプである。
- ただのobjectはiterableではない。
- Iteratorを使い、IterableなオブジェクトのSymbol.iterator関数を呼び出す。
target
- es3 or es5
- Arrayのみfor..ofを使える
- オブジェクトに使うとエラー
- es6
- SYmbol.iteratorを具現すると、どんなオブジェクトにもfor..ofを使える
typescriptのIteratorインタフェース
1 | // lib.es6.d.ts |
Iterable具現
1 | class CustomIterable implements Iterable<string> { |
12. Decorator
- Decoratorを使うためには、config設定必要
- 各Decoratorパターンに対するシグニチャーを見ておくこと
Setting
1 | $ mkdir ts-decorator |
Class Decorator Example
1 | function hello(constructFn: Function) { |
1 | function editable(canBeEdit: boolean) { |
1 | function addHello(constructorFn: Function) { |
Method Decorator Example
1 | function editable(canBeEdit: boolean) { |
Property Decorator
1 | function writable(canBeWrite: boolean) { |
Parameter Decorator
1 | function printInfo(target: any, methodName: string, paramIndex: number) { |
13. Type Inference
- タイプを明示しなかった場合のタイプ推論規則
- letは、基本データ・タイプで推論
- constはリタラル・タイプで推論
- objectタイプを使わないと、プロパティはletと同じように推論
- const person = {name:’Mark’, age: 35}
- person => {name: string; age: number;}で推論される
- objectタイプを使わないと、プロパティはletと同じように推論
- 大体は推論自体は簡単
- 単純な変数
- structuring, destructuring
- array, 関数のリターンに対しては推論が難しい場合が多い
ArrayのType Inference
1 | const array1 = []; |
returnのType Inference
1 | function hello(message: string | number) { |
Union TypeとType Guard
1 | interface Person { |