はじめに
TypeScriptはJavaScriptに静的型付けを導入したスーパーセット(上位互換)な言語です。
静的型付けされるのでJavaScriptより大規模な開発に向いています。
僕自身が小規模案件より中規模案件を担当することが増えてきていて、今後ももっと中規模案件を管理するためにTypeScriptの導入を進めています。
新しい言語ということでまだまだ枯れていないTypeScriptなのですが「2018年現在、とりあえずTypeScript書きたいな」という場面のために何をすれば良いかをまとめてみました。
TypeScript本体は2018年8月時点でバージョン3.0.1を使っています。
次にJSガッツリ書くときはTypeScriptで
Microsoft、JavaScriptのスーパーセット「TypeScript」を発表
前準備(Gitと.gitignoreとpackages.jsonの準備)
新しい言語や仕組みを使うときはGit化しておくと振り返りが出来るので良いです。
$ git init
Initialized empty Git repository in /Users/yousan/git/ts_ex2/.git/
yarn
を使ってpackages.json
も作成しておきます。-y
オプションを渡すとデフォルトの値で対話を埋めてくれます。
$ yarn init -y
yarn init v0.16.1
warning The yes flag has been set. This will automatically answer yes to all questions which may have security implications.
success Saved package.json
✨ Done in 0.13s.
node_modules
などはGit管理から外したいのでgibo
を使って.gitignore
を作成します。
$ gibo -u ; gibo Node >> .gitignore
gibo
はNode.jsやPHPといった各種パッケージ用の.gitignore
を作ってくれるボイラーテンプレートで、「こういうのを省いとくと良いんやで」って教えてくれます。
特に慣れていない言語やパッケージのときには便利です。
気付いたら.gitignoreはgiboで自動生成する時代になっていた
実際に作成されるNode.js用のボイラーテンプレートはこんな感じです。
### https://raw.github.com/github/gitignore/318f8fc99146275e0828737ac2898930c6d8342f/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
インストール
yarnでTypeScript本体とNode.js標準モジュールの型定義ファイルをインストールします。
$ yarn add typescript @types/node
yarn add v0.16.1
info No lockfile found.
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
^R
success Saved lockfile.
success Saved 1 new dependency
└─ typescript@3.0.1
✨ Done in 1.17s.
TypeScript用の設定ファイルを初期化します。
$ yarn tsc -- --init
yarn tsc v0.16.1
$ "/Users/yousan/git/ts_ex2/node_modules/.bin/tsc" --init
message TS6071: Successfully created a tsconfig.json file.
✨ Done in 0.39s.
tsc
はTypeScriptのコンパイラです(tsc:= Type Script Compiler)
-- --init
と書くとサブコマンドにオプションを渡してくれます。
(--init
だけだとyarn
コマンド側のオプションになってしまいます)
余談ですがyarn tsc
のようにサブコマンドっぽく呼ぶと、node_modules/.bin/tsc
といったyarn(npm)で入っている実行ファイルを呼び出せます。npm
の場合だとBashであれば$(npm bin)/tsc
と書くといい感じに動くんですが、コマンドラインの補完が効きづらいのでyarn
の方が書きやすいですね。
tsc --init
で作成されるtsconfig.json
です。
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}
}
これも余談ですが、tsconfig.json
はコメントありJSONになっています。
JSON規格だとコメント機能はありませんが、TypeScriptでは独自にコメント機能を実装しています。
Allow comments in tsconfig.json
個人的にはJSON自体にコメント機能や末尾のカンマ(final commas)を許可して欲しいです。
TypeScriptを動かしてみる
const main = () => {
const str: string = 'Hello TypeScript!';
console.log(str);
}
main()
コンパイルしてNode.jsとして実行します。
$ $(npm bin)/tsc hoge.ts
$ ls
hoge.js hoge.ts node_modules package.json tsconfig.json yarn.lock
$ node hoge.js
Hello TypeScript!
動きました!
hoge.ts
からhoge.js
にコンパイルされています。
中身はこんな感じです。
var main = function () {
var str = 'Hello TypeScript!';
console.log(str);
};
main();
型ファイルを探す(DefnitlyTypedとTypeSearch)
TypeScriptでnpmなどから提供されているライブラリを使う場合には型定義ファイルが必要です。
多くの型ファイルは「npmのパッケージ名」に@types/
をつけてyarn add
します。
例えばjs-yaml
というライブラリを型定義ファイルごと一緒にインストールする場合にはこんな感じです。
$ yarn add js-yaml @types/js-yaml
yarn add v0.16.1
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency
└─ @types/js-yaml@3.11.2
✨ Done in 0.63s.
@types
で管理されている型定義ファイルはTypeSearchで検索することが出来ます。
TypingsやtsdはDeprecated(非推奨)
過去のTypeScriptバージョン1時代は型定義ファイルのリポジトリ集としてtypingsやtsdがあったのですが、いまは使われていません。
This package has been deprecated
Author message:
Typings is deprecated in favor of NPM @types -- see README for more information
npmでTypeScriptの型定義を管理できるtypesパッケージについて
TypeScript の型定義ファイルと仲良くなろう
TypeScriptの型定義管理ツールTypingsについて
TypeScriptのtsdが非推奨になったので、typingsへ移行
tsdからTypingsに移行されたのが2016年とのことで、この辺の流れは本当に早いですね。
Node.js標準系の型定義ファイル
fs
などのNode.js標準モジュールは@types/fs
にはありません。
$ yarn add --dev @types/fs
yarn add v0.16.1
[1/4] 🔍 Resolving packages...
error An unexpected error occured, please open a bug report with the information provided in "/Users/yousan/git/swagger-yaml-to-html/convert/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
怒られてしまいますね。
標準形モジュールは@types/node
を入れておきます。
$ yarn add @types/node
yarn add v0.16.1
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
warning Unmet peer dependency "babel-core@^6.0.0 || ^7.0.0-0".
warning Unmet peer dependency "babel-jest@^23.0.0 || ^24.0.0".
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency
└─ @types/node@10.9.2
✨ Done in 6.44s.
typescriptでnodeのfsを動かそうとしてハマったこと
TypeScriptの型ファイルが無い場合
@types
に型定義ファイルがない場合もあります。
$ npm install --save-dev @types/yaml
npm ERR! code E404
npm ERR! 404 Not Found: @types/yaml@latest
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/yousan/.npm/_logs/2018-08-25T12_46_09_186Z-debug.log
自分で型定義ファイル(もどき)を作成することでコンパイルエラーは回避できます。
declare module '*';
import * as hoge from 'yaml';
ただし実行時にエラーになってしまう可能性があるので注意が必要です。
TypeScriptで型定義されていないモジュールを読み込む方法
importの仕方
import * as ... from '...'
です。
import * as fs from 'fs';
fs.readFileAsync('/path/to/file.txt');
TypeScript 2.7.1 以降での import の書き方
Jestの導入
JestはFacebook社製のテストツールです。
JavaScriptのテストツールといえばchai, Mocha, enzyme, Jasmineといろいろとあったのですが、2018年でモダンでTypeScriptっぽいテストツールはJestらしいです。
TypeScriptとJestのチュートリアルはこちらにきれいにまとまっています。
下記の記事にJestの使い方が網羅されているのでかなり便利です。
Facebook製のJavaScriptテストツール「Jest」の逆引き使用例
Jestのインストール
Yarn(npm)でJestと型定義ファイルをインストールします。
$ yarn add --dev typescript jest ts-jest @types/jest
yarn add v0.16.1
[1/4] 🔍 Resolving packages...
warning jest > jest-cli > istanbul-api > istanbul-lib-hook@1.2.1: 1.2.0 should have been a major version bump
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 618 new dependencies.
├─ @babel/code-frame@7.0.0-rc.3
├─ @babel/generator@7.0.0-beta.51
│ └─ jsesc@2.5.1
├─ @babel/helper-function-name@7.0.0-beta.51
├─ @babel/helper-get-function-arity@7.0.0-beta.51
├─ @babel/helper-split-export-declaration@7.0.0-beta.51
...(中略)...
├─ write-file-atomic@2.3.0
├─ ws@5.2.2
├─ xml-name-validator@3.0.0
├─ y18n@3.2.1
├─ yallist@2.1.2
├─ yargs-parser@9.0.2
└─ yargs@11.1.0
✨ Done in 17.27s.
Yarn(npm)のサブコマンドのtest
でJestが動くようにしておきます。
{
"devDependencies": {
"@types/jest": "^23.3.1",
"jest": "^23.5.0",
"ts-jest": "^23.1.4",
"typescript": "^3.0.1"
},
"name": "ts_ex2",
"version": "1.0.0",
"main": "index.js",
"author": "Yousan_O <yousan@l2tp.org>",
"dependencies": {
"@types/js-yaml": "^3.11.2",
"js-yaml": "^3.12.0"
},
"scripts": {
"test": "jest"
}
}
この状態でテストが動くことを確認しておきます。
$ yarn test
yarn test v0.16.1
$ jest
No tests found
In /Users/yousan/git/ts_ex2
3 files checked.
testMatch: **/__tests__/**/*.js?(x),**/?(*.)+(spec|test).js?(x) - 0 matches
testPathIgnorePatterns: /node_modules/ - 3 matches
Pattern: - 0 matches
error Command failed with exit code 1.
テストファイルが無いのでエラーになりましたが、ちゃんと動いていますね♪
実際にテストを動かしてみる
export function sampleFunction(x: string): string {
return x + x;
}
import { sampleFunction } from "../src";
describe("This is a simple test", () => {
test("Check the sampleFunction function", () => {
expect(sampleFunction("hello")).toEqual("hellohello");
});
});
$ yarn test
yarn test v0.16.1
$ jest
PASS __tests__/base.spec.ts
This is a simple test
✓ Check the sampleFunction function (4ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.347s, estimated 2s
Ran all test suites.
✨ Done in 1.99s.
うまくテストが動いていますね!
Jestでコードカバレッジ(テストの網羅率)を出す
Jestではカバレッジを出力することが出来ます。
下記のようにcollectCoverage
をjest.config.js
に追記します。
(以前はmapCoverage
も必要だったようですが、現在はDeprecatedになりました。)
module.exports = {
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
collectCoverage: true,
};
動かしてみます。
$ yarn jest
yarn jest v0.16.1
$ "/Users/yousan/git/ts_ex2/node_modules/.bin/jest"
PASS __tests__/base.spec.ts
This is a simple test
✓ Check the sampleFunction function (8ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.706s
Ran all test suites.
✨ Done in 4.12s.
うまく動きましたね!
Qiitaのハイライト(Bashシンタックス)だと赤くなってしまっていますが、カバレッジが高い箇所はグリーンになっていて気分が良いですね😋

CIで動かす

中規模開発には欠かせないCIを導入します。
オープンソース(OSS)界隈ではTravisがよく使われているのですが、ここではCircleCIを利用します。
Travisに比べると
「プライベートリポジトリが時間制限付きで無料(慣れるまでには十分な無料枠です)」
「Dockerと相性が良い」
「デプロイやスケジューリングといったWorkFlowという概念が発達している」
「ローカルでCIのテストができる(完璧ではないですが)」
「CIで走ったジョブに対してSSHで接続できる」
っといたメリットがあります。
CircleCI2.0のWorkflowを試してみる
CircleCI 2.0 をlocalで動かす
CircleCI導入
CircleCIを開いてGitHubでログインし、左側のメニューから「Add Projects」を選択します。

GitHubと連携していればGitHubのリポジトリが見えるので、今回のリポジトリを「SetUp Project」します。
言語は自動判別されていて、今回はそのまま「Node」を選びます。

画面中央部分にあるPopulate the config.yml with the contents of the sample .yml (shown below).
の「Copy To Clipboard」でサンプルのconfig.ymlをコピーします。
これをリポジトリに作成し貼り付けます。
$ mkdir .circleci
$ cat > .circleci/config.yml
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:7.10
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: yarn install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
# run tests!
- run: yarn test
完了したらGitでコミットプッシュします。
ga -m 'for circle'
[master e22e2b0] for circle
2 files changed, 38 insertions(+)
create mode 100644 .circleci/config.yml
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 859 bytes | 859.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:yousan/ts_ex2.git
51b7562..e22e2b0 master -> master
ga -m
はgit add...
の省略形です。
git add --all; git commit -m 'first commit'; git push --all を省略化する
先ほどのブラウザの画面から「Start Building」をクリックして初回のビルドを走らせます。
うまくいくと… オールグリーンでテスト完了です!

気分が良いですね😋
GitHubとの連携
GitHubの方でもテストにパスをしたグリーンのチェックマークが付きます。

CircleCIではテストだけではなくビルド、デプロイなどいろいろなことが出来ます。
まずはテストを自動で通しておくようにすれば中規模開発で非常に役立ちます。
僕が管理しているチーム開発では、機能を開発する際にブランチを切り、マージの際にプルリクエストで投げてもらうようにしています。
そうすることでCIとプルリクマージを組み合わせることでテストをパスすることが保証されるので、コードの品質が保たれます。
もちろんですがちゃんとした開発の場合にはテストのカバレッジや品質も重要です。テストを自動化することで次のステップに注力することが出来ます。
この仕組は中規模を意識した開発では最低限の品質保証としてとても強力です。
コーディング規約に準拠する
中規模案件を回す際、コーディング規約を定めると良いです。
特に複数人がコードの同じ箇所をメンテナンスする場合にはコーディング規約があったほうが良いです。逆にコーディング規約が無いとどんどん崩壊していきます。
Standard

最近注目のJSLintツール、Standard(Standard JS)です。
TypeScript用にstandard typescript-eslint-parser eslint-plugin-typescript
をインストールします。
$ yarn add standard typescript-eslint-parser eslint-plugin-typescript --dev
yarn add v0.16.1
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
warning Unmet peer dependency "babel-core@^6.0.0 || ^7.0.0-0".
warning Unmet peer dependency "babel-jest@^23.0.0 || ^24.0.0".
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 118 new dependencies.
├─ acorn-jsx@3.0.1
...
動かす場合にはオプションをつけてstandard
コマンドを呼び出します。
$ yarn standard standard -- --parser typescript-eslint-parser --plugin typescript *.ts
yarn standard v0.16.1
$ "/Users/yousan/git/ts_ex2/node_modules/.bin/standard" standard --parser typescript-eslint-parser --plugin typescript hoge.ts
standard: Use JavaScript Standard Style (https://standardjs.com)
standard: Run `standard --fix` to automatically fix some problems.
/Users/yousan/git/ts_ex2/hoge.ts:2:1: Expected indentation of 2 spaces but found 6.
/Users/yousan/git/ts_ex2/hoge.ts:3:1: Expected indentation of 2 spaces but found 6.
error Command failed with exit code 1.
この例では「スペースは6じゃなくて2を使ってね!」というエラーで怒られました。
--fix
オプションをつけると自動で修正してくれます。
yarn standard standard -- --parser typescript-eslint-parser --plugin typescript *.ts --fix
yarn standard v0.16.1
$ "/Users/yousan/git/ts_ex2/node_modules/.bin/standard" standard --parser typescript-eslint-parser --plugin typescript hoge.ts --fix
✨ Done in 1.75s.
diff --git a/hoge.ts b/hoge.ts
index 0836004..b052802 100644
--- a/hoge.ts
+++ b/hoge.ts
@@ -1,6 +1,6 @@
const main = () => {
- const str: string = 'Hello TypeScript!';
- console.log(str);
+ const str: string = 'Hello TypeScript!'
+ console.log(str)
}
main()
Standardはめっちゃお手軽にコーディング規約を導入できることが強みです。
ただセミコロン無しというのは…、賛否が分かれるところですね。
デフォルトオプションの設定
packages.json
のstandard
の項目にTypeScript用のデフォルトオプションを指定できます。
"standard": {
"parser": "typescript-eslint-parser",
"plugins": [ "typescript" ]
}
これで気軽に呼べます。
$ yarn standard standard -- *.ts --fix
yarn standard v0.16.1
$ "/Users/yousan/git/ts_ex2/node_modules/.bin/standard" standard hoge.ts --fix
✨ Done in 1.75s.
ブラウザで動かすwebpack
Babelのインストール
$ yarn add babel
yarn add v0.16.1
[1/4] 🔍 Resolving packages...
warning babel@6.23.0: In 6.x, the babel package has been deprecated in favor of babel-cli. Check https://opencollective.com/babel to support the Babel maintainers
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency
└─ babel@6.23.0
✨ Done in 0.50s.
謝辞
今回のTypeScriptを導入するにあたって @naname さん、 @kurouw さんに色々と教えてもらいました。
TypeScriptが流行していること、その理由、中規模に向いていること、TypeScriptの書き方、コーディング規約、テストの重要性。大切なことを教えてもらいました。重ねてありがとうございます!