- TypeScript
TypeScript入門|インストールからtscで実行するまでの始め方
TypeScriptを始める手順は、「npmでtypescriptを入れる → tsc --initで設定ファイルを作る → tscでJavaScriptに変換する → nodeで実行する」の4段階です。 この記事では、空のフォルダから最初の1ファイルが動くまでを、打ったコマンドと表示された出力をそのまま並べて進めます。
確認環境:Ubuntu 24.04、Node.js 22.22.2 と 24.21.0、npm 10.9.7、TypeScript 7.0.2、@types/node 22.20.5。掲載した出力は、すべてこの環境で実際に表示されたものです。TypeScript 7 系では tsc --init が作る tsconfig.json の中身が以前の版と変わっているので、生成されたファイルの全文と、その設定で最初に出会いやすいエラーも順に取り上げます。
TypeScriptの始め方の早見表
コマンドの流れ
| 順番 | やること | コマンド | できるもの |
|---|---|---|---|
| 1 | フォルダを作って npm の準備 | mkdir hello-ts && cd hello-ts && npm init -y |
package.json |
| 2 | TypeScript を入れる | npm install --save-dev typescript |
node_modules、package-lock.json |
| 3 | 版を確かめる | npx tsc --version |
Version 7.0.2 と表示 |
| 4 | 設定ファイルを作る | npx tsc --init |
tsconfig.json |
| 5 | コードを書く | src/index.ts を作る | .ts ファイル |
| 6 | JavaScript に変換する | npx tsc |
dist/index.js など |
| 7 | 実行する | node dist/index.js |
画面に結果 |
| 8 | 型だけ確かめる | npx tsc --noEmit |
ファイルは作らず、エラーだけ表示 |
最初につまずく点(すべて実際に出たエラー)
| 番号 | 出る場面 | 直し方 |
|---|---|---|
| TS2322 | 型注釈と違う型の値を代入した | 注釈か値のどちらかを合わせる |
| TS2345 | 関数に渡した引数の型が違う | 引数の型を合わせる |
| TS5112 | tsconfig.json があるのに npx tsc src/index.ts とファイル名を付けた |
ファイル名を付けずに npx tsc と打つ |
| TS2591 | process などNode.jsの機能を使った |
npm install --save-dev @types/node を入れ、types に "node" を書く |
| TS1287 / TS1295 | import / export を書いた | package.json に "type": "module" を足す |
| TS2835 | import ... from "./greet" と拡張子なしで書いた |
"./greet.js" と拡張子を付ける |
| (番号なし) | tsc だけ打ったら別の版が動いた |
npx tsc と打って、フォルダに入れた版を使う |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「TypeScript入門|インストールからtscで実行するまでの始め方」
TypeScriptとtscの役割を30秒でつかむ
TypeScriptは、JavaScriptに型の注釈(この変数は文字列、この引数は数値、といった目印)を書けるようにした言語です。Node.jsやブラウザが動かすのはJavaScriptなので、次の2つの作業が必要になります。
| 作業 | 内容 | 担当 |
|---|---|---|
| 型チェック | 注釈と実際の使い方が合っているかを、動かす前に調べる | tsc |
| 変換(コンパイル) | 型の注釈を取り除いて .js ファイルを作る | tsc |
| 実行 | できあがった .js を動かす | node |
tsc は TypeScript に付いてくるコマンドで、型チェックと変換の両方を受け持ちます。 この記事は、その tsc を自分のフォルダに入れて使うところまでを扱います。
手順1:フォルダを作ってnpm initする
Node.js が入っていることを確かめてから、作業用のフォルダを作ります。
node -v
npm -v
v22.22.2
10.9.7
mkdir hello-ts
cd hello-ts
npm init -y
Wrote to /home/taro/hello-ts/package.json:
{
"name": "hello-ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
フォルダのパスは環境に合わせて /home/taro に置き換えて表示しています。package.json は、このフォルダで使う道具(パッケージ)の一覧を記録するファイルです。
手順2:TypeScriptをインストールして版を確かめる
npm install --save-dev typescript
added 2 packages, and audited 3 packages in 1s
found 0 vulnerabilities
--save-dev は「開発のときだけ使う道具」として記録する指定です。package.json に次の行が増えます。
"devDependencies": {
"typescript": "^7.0.2"
}
入った版は npx tsc --version で確かめます。npx は、このフォルダの node_modules に入っているコマンドを動かすための仕組みです。
npx tsc --version
Version 7.0.2
tscだけ打つと別の版が動くことがある
確認環境には、以前に別の版の TypeScript がパソコン全体(グローバル)に入っていました。そこで npx を付けずに打つと、次のようになりました。
tsc --version
Version 6.0.3
フォルダに入れた版を確実に使うには、いつも npx tsc と打ちます。 npx を付ければ、グローバルの状態に関係なく同じ結果になります。
手順3:tsc --initでtsconfig.jsonを作る
tsconfig.json は、tsc の動き方を決める設定ファイルです。ひな形はコマンドで作れます。
npx tsc --init
Created a new tsconfig.json
You can learn more at https://aka.ms/tsconfig
TypeScript 7.0.2が生成したtsconfig.jsonの全文
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// File Layout
// "rootDir": "./src",
// "outDir": "./dist",
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "esnext",
"types": [],
// For nodejs:
// "lib": ["esnext"],
// "types": ["node"],
// and npm install -D @types/node
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Style Options
// "noImplicitReturns": true,
// "noImplicitOverride": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// "noPropertyAccessFromIndexSignature": true,
// Recommended Options
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true,
}
}
全部で40行ほどの短いファイルです。// で始まる行はコメントで、効いていません。最初の1ファイルを動かすうえで関係するのは次の5つです。
| 項目 | 生成時の値 | 最初の1ファイルへの影響 |
|---|---|---|
| rootDir / outDir | コメントのまま | 有効にすると、src の .ts が dist に .js として出る(次の手順で有効にする) |
| module | nodenext | Node.js と同じ決まりで import / export を扱う。package.json の type の有無で結果が変わる |
| types | 空の配列 | Node.js の型(process など)は読み込まれない。使うときは "node" を書く |
| strict | true | 型のチェックを厳しめにする。入門のうちから有効のままで進められる |
| verbatimModuleSyntax | true | import / export を書いたとおりに出力する。type の指定がないと TS1287 / TS1295 になる |
出力先をdistに分ける
生成されたままだと、.js は .ts と同じ場所に作られます。ソースと成果物を分けるために、コメントになっている2行の // を外します。
// File Layout
"rootDir": "./src",
"outDir": "./dist",
手順4:最初のTypeScriptを書いてtscで変換する
src フォルダを作り、src/index.ts に次の内容を書きます。
function greet(name: string, times: number): string {
return `こんにちは、${name}さん!`.repeat(times);
}
const message: string = greet("TypeScript", 2);
console.log(message);
name: string や times: number が型の注釈です。変換は、ファイル名を付けずに tsc とだけ打ちます。
npx tsc
問題がなければ何も表示されずに終わり、dist フォルダに4つのファイルができます。
ls dist
index.d.ts
index.d.ts.map
index.js
index.js.map
| ファイル | 中身 | 作られる理由 |
|---|---|---|
| index.js | 実行する JavaScript | 変換の本体 |
| index.js.map | .js と .ts の行の対応表 | sourceMap が true |
| index.d.ts | 型の情報だけを抜き出したもの | declaration が true |
| index.d.ts.map | .d.ts と .ts の対応表 | declarationMap が true |
dist/index.js を開くと、型の注釈だけが取り除かれているのがわかります。
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function greet(name, times) {
return `こんにちは、${name}さん!`.repeat(times);
}
const message = greet("TypeScript", 2);
console.log(message);
//# sourceMappingURL=index.js.map
手順5:nodeで実行する
node dist/index.js
こんにちは、TypeScriptさん!こんにちは、TypeScriptさん!
Node.js 22.22.2 と 24.21.0 のどちらでも同じ結果でした。ここまでで「書く → tsc → node」の一周が完成です。
型エラーをわざと起こして読み方を覚える
TypeScript のよさは、動かす前に食い違いを教えてくれる点です。エラーの読み方を一度体験しておくと、その後がとても楽になります。
TS2322:注釈と違う型を代入した
src/index.ts の5行目の注釈を string から number に変えます。
const message: number = greet("TypeScript", 2);
npx tsc
src/index.ts(5,7): error TS2322: Type 'string' is not assignable to type 'number'.
日本語で読みたいときは --locale ja を付けます。
npx tsc --locale ja
src/index.ts(5,7): error TS2322: 型 'string' を型 'number' に割り当てることはできません。
エラーの1行は、次の4つの部品でできています。
| 部品 | 例 | 意味 |
|---|---|---|
| 場所 | src/index.ts(5,7) |
ファイル名と(行, 列)。5行目の7文字目 |
| 番号 | TS2322 |
エラーの種類。検索するときの手がかり |
| 実際の型 | 'string' |
greet が返す値の型 |
| 期待された型 | 'number' |
注釈に書いた型 |
直し方は、注釈を string に戻すことです。 greet は文字列を返す関数なので、受け取る側を合わせます。
const message: string = greet("TypeScript", 2);
TS2345:引数の型が違う
今度は、2つ目の引数を文字列の "2" にしてみます。
const message: string = greet("TypeScript", "2");
src/index.ts(5,45): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
src/index.ts(5,45): error TS2345: 型 'string' の引数を型 'number' のパラメーターに割り当てることはできません。
引数を数値の 2 に戻せば解消します。
エラーがあるときの終了コードとファイルの出力
エラーが出た状態で、3通りの打ち方の終了コード(echo $? で見られる数字)を比べました。
| コマンド | 終了コード | dist の .js |
|---|---|---|
npx tsc |
2 | 作られる(エラーがあっても出力される) |
npx tsc --noEmit |
1 | 作られない(型チェックだけ) |
npx tsc --noEmitOnError |
1 | 作られない(エラーがあれば出力を止める) |
エラーが残っていても、npx tsc は .js を出力します。 型だけを手早く確かめたいときは npx tsc --noEmit が便利です。
最初につまずく点と直し方
ここからは、生成されたままの tsconfig.json で実際に出たエラーと、その直し方です。
TS5112:tscにファイル名を付けるとtsconfig.jsonが読まれない
入門記事でよく見る「tsc ファイル名」の形を、tsconfig.json があるフォルダで打つと止まります。
npx tsc src/index.ts
error TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.
error TS5112: tsconfig.json は存在しますが、コマンドラインでファイルが指定されている場合は読み込まれません。このエラーをスキップするには、'--ignoreConfig' を使用します。
ファイル名を付けると tsconfig.json は使われない、という決まりを知らせてくれるエラーです。
| やりたいこと | 打ち方 | 結果 |
|---|---|---|
| tsconfig.json の設定で変換する | npx tsc |
dist に出力される |
| 設定を使わず1ファイルだけ変換する | npx tsc --ignoreConfig src/index.ts |
src/index.js が .ts の隣に作られる |
tsconfig.json を作ったら、ファイル名は付けずに npx tsc と打つ、と覚えておけば十分です。
TS2591:processなどNode.jsの機能が見つからない
コマンドの引数を受け取るように、src/index.ts を書き換えます。
const name: string = process.argv[2] ?? "TypeScript";
console.log(`こんにちは、${name}さん!`);
src/index.ts(1,22): error TS2591: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
生成された tsconfig.json は types が空の配列なので、Node.js 用の型は自動では読み込まれません。エラー文に書かれているとおり、2つの作業をします。
npm install --save-dev @types/node@22
"types": ["node"],
@types/node の番号は、使っている Node.js のメジャー番号(22 や 24)に合わせます。直したあとの結果です。
npx tsc
node dist/index.js RJC
node dist/index.js
こんにちは、RJCさん!
こんにちは、TypeScriptさん!
TS1287・TS1295:importとexportを書いたら止まる
ファイルを2つに分けてみます。src/greet.ts を新しく作ります。
export function greet(name: string): string {
return `こんにちは、${name}さん!`;
}
src/index.ts は次のようにします。
import { greet } from "./greet";
console.log(greet(process.argv[2] ?? "TypeScript"));
src/greet.ts(1,1): error TS1287: A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled.
src/index.ts(1,10): error TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'. Adjust the 'type' field in the nearest 'package.json' to make this file an ECMAScript module, or adjust your 'verbatimModuleSyntax', 'module', and 'moduleResolution' settings in TypeScript.
npm init -y で作った package.json には type の指定がないため、.ts ファイルは CommonJS(require を使う従来の形式)として扱われます。そこへ import / export を書いたので、verbatimModuleSyntax の決まりと食い違いました。package.json に "type": "module" を足すと、ECMAScript モジュール(import / export を使う形式)として扱われます。
npm pkg set type=module
TS2835:importの拡張子を省いた
type を足してもう一度 tsc を動かすと、次のエラーに変わります。
src/index.ts(1,23): error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './greet.js'?
src/index.ts(1,23): error TS2835: 相対インポート パスでは、'--moduleResolution' が 'node16' または 'nodenext' である場合、ECMAScript インポートに明示的なファイル拡張子が必要です。'./greet.js' を意図していましたか?
Node.js の ECMAScript モジュールでは、相対パスの import に拡張子が必要です。エラー文の提案どおり、変換後のファイル名である .js を書きます。
import { greet } from "./greet.js";
console.log(greet(process.argv[2] ?? "TypeScript"));
npx tsc
node dist/index.js
こんにちは、TypeScriptさん!
dist/index.js は、import 文がそのまま残った形で出力されます。
import { greet } from "./greet.js";
console.log(greet(process.argv[2] ?? "TypeScript"));
//# sourceMappingURL=index.js.map
npm scriptsにまとめて打つ量を減らす
毎回のコマンドは、package.json の scripts に名前を付けて登録できます。
npm pkg set scripts.build=tsc scripts.start="node dist/index.js" scripts.typecheck="tsc --noEmit"
npm pkg delete scripts.test
ここまでの手順を終えた package.json の全文です。
{
"name": "hello-ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"typecheck": "tsc --noEmit"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^22.20.5",
"typescript": "^7.0.2"
},
"type": "module"
}
scripts の中では npx を付けなくても、フォルダに入れた tsc が使われます。
npm run build && npm start
> hello-ts@1.0.0 build
> tsc
> hello-ts@1.0.0 start
> node dist/index.js
こんにちは、TypeScriptさん!
保存のたびに自動で変換する
--watch を付けると、tsc が動き続けて、ファイルを保存するたびに変換し直します。
npx tsc --watch
05:24:11 PM - Starting compilation in watch mode...
05:24:11 PM - Found 0 errors. Watching for file changes.
止めるときは Ctrl + C を押します。
完成したフォルダの構成
hello-ts/
├── dist/ (tsc が作る。greet.js、index.js と .map、.d.ts)
├── node_modules/ (npm install が作る)
├── src/
│ ├── greet.ts
│ └── index.ts
├── package-lock.json
├── package.json
└── tsconfig.json
よくある質問
Q. TypeScriptはパソコン全体(グローバル)に入れるほうがよいですか?
A. フォルダごとに npm install --save-dev typescript で入れる方法をおすすめします。package.json に版が記録されるので、別のパソコンでも npm install だけで同じ版がそろいます。確認環境ではグローバルに 6.0.3 が入っていて、tsc だけ打つとそちらが動きました。npx tsc ならフォルダの 7.0.2 が使われます。
Q. エラーが出ているのに dist に .js ができているのはなぜですか?
A. npx tsc は、型エラーがあっても変換結果を出力する動きになっているためです(終了コードは 2)。エラーがあるときに出力を止めたい場合は --noEmitOnError、型チェックだけしたい場合は --noEmit を付けます。
Q. import に .ts ではなく .js と書くのはなぜですか?
A. 実行されるのは変換後の dist/index.js で、その隣にあるのは greet.js だからです。tsc は import のパスを書き換えずに出力するので、最初から実行時のファイル名で書いておきます。TS2835 のエラー文も ./greet.js を提案してくれます。
Q. エラー文を日本語で読めますか?
A. npx tsc --locale ja で日本語になります。検索するときは TS2322 のような番号を使うと、言語に関係なく情報を探せます。
まとめ
- 始め方は4段階:npm install --save-dev typescript → npx tsc --init → npx tsc → node dist/index.js
- コマンドは npx tsc と打つ:フォルダに入れた版(今回は 7.0.2)が確実に使われる
- tsc --init のあと rootDir と outDir のコメントを外すと、src から dist へ出力が分かれる
- エラーは「場所・番号・実際の型・期待された型」で読む。TS2322 は代入、TS2345 は引数の食い違い
- tsconfig.json があるときはファイル名を付けない。付けると TS5112 で止まる
- Node.js の機能を使うなら @types/node と types: ["node"]、import / export を使うなら "type": "module" と拡張子 .js
- 型だけ確かめるなら npx tsc --noEmit。scripts に build / start / typecheck を登録しておくと打つ量が減る
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「TypeScript入門|インストールからtscで実行するまでの始め方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。