TypeScriptでthisの型を指定する

JavaScriptでは、thisの型が変わることがあります。

class Sample {
    hello() { console.log(this.constructor.toString()); }
}

const sample = new Sample();
sample.hello(); //(1) => function Sample() {}

let hello = sample.hello; 
hello(); //(2) => function Object() { [native code] }

(1)ではthisはSample型でしたが、(2)ではObject型になりました。

関数の使い方を誤ってthisが想定外の型になり、思わぬエラーになることがあります。

TypeScriptでは、関数の1番目の引数をthisにすることで、thisの型を指定できます。

class Sample {
    hello(this: Sample) { console.log(this.constructor.toString()); }
}

thisは仮の引数であり、実際には存在しません。
関数を呼び出すときは、引数thisを指定する必要はありません。

先ほどのコードをコンパイルすると(2)のところで、コンパイルエラーになります。

const sample = new Sample();
sample.hello();

let hello = sample.hello;
hello(); //(2) error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Sample'.

コンパイラに「–noImplicitThis」オプションを渡すと、関数内でthisの型を指定せずにthisを使うとエラーになります。

class Sample {
    name: string = "hello";
}
function hello() { console.log(this.name); }

hello.bind(new Sample())(); //=> error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.

JavaScriptではthisにまつわるトラブルが起こりがちです。

TypeScriptで「–noImplicitThis」をつけてthisの型を忘れずに指定すれば、安全なプログラミングができそうです。

WindowsのKeePassでパスワードを入力するときに日本語入力をOFFにする

KeePassとは

KeePassは無料で使えるパスワード管理ソフトです。

メールやFacebook、Amazon、その他Webサイトで同じパスワードを使い回していると、一つのサービスでパスワードが漏洩したとき、他のすべてのサービスのアカウントも危険にさらされます。

とはいえ、サービスごとに異なるパスワードを使い分けると、たくさんのパスワードを管理するのが大変になります。

そこで、パスワード管理ソフトの出番です。

パスワード管理ソフトは有名なものがいくつかありますが、比較した結果、KeePassを使うことにしました。

KeePassはオープンソースで開発されているので、無料で使用でき、Windows/macOS/Android/iOSでも使用できます。

WindowsのKeePassでパスワードを入力するときに日本語入力をOFFにする

しばらくの間、KeePassを使っていて気になったところがありました。

KeePassには、入力欄に自動で入力する機能があります。
日本語入力がONになった状態で自動入力機能を実行すると、日本語入力がONのまま、ひらがなでユーザー名やパスワードを入力してしまいます。

そこで、KeePassの自動入力を行うときに、日本語入力をOFFにする方法を調べました。

日本語入力は、変換キーでON、無変換キーでOFFにするように設定しています。

KeePassの自動入力実行時に、無変換キーを押すことができれば解決です。

KeePassでは無変換キーは「{VKEY 29}」になります。
「{VKEY 29}」をユーザー名の前に追加すれば、入力前に日本語入力をOFFにできます。

設定方法は次のようになります。

KeePassを起動したら、フォルダーを右クリックして、「グループを編集」を選択します。

「自動入力」タブを選択します。

「標準の手順を上書き」をチェックして、次のように入力します。

{VKEY 29}{USERNAME}{TAB}{PASSWORD}{ENTER}

「OK」ボタンを押して、設定を反映します。

以上で完了です。

参考

次のページを参考にしました。

ありがとうございました。

WindowsのATOKで日本語入力のON/OFFを変換/無変換キーに割り当てる

Windowsでは「全角/半角」キーを押して日本語入力のON/OFFを切り替えます。

「変換」キーで日本語入力をONに、「無変換」キーで日本語入力をOFFにするように設定すると、現在の日本語入力の状態がONかOFFかを意識する必要がなくなり、入力切り替えのトラブルがなくなります。

Windows 10のATOK 2017で、変換キーを押すと日本語入力をONにし、無変換キーを押すと日本語入力をOFFにする設定方法です。
他のバージョンのATOKも同じ手順で設定できます。

タスクバーのATOKのメニューアイコンをクリックして、ポップアップメニューから「プロパティ(環境設定)」を選択、または日本語入力をONにして「CTRL+F12」キーを押します。

「ATOKプロパティ」画面が表示されました。

「キー・ローマ字・色」タブを選択し、スタイル一覧から「キーカスタマイズ」ボタンを押します。

「ATOKキーカスタマイズ」画面が表示されました。

「機能を検索」ボタンを押します。

「検索」画面が表示されました。

機能一覧から「日本語入力ON」を選択して、「OK」ボタンを押します。

「ATOKキーカスタマイズ」画面に戻りました。
「設定一覧」では、「日本語入力ON」が選択されています。

「変更」ボタンを押します。

「キーの変更」画面が表示されました。

「メニュー」から「キーボードから変更」を選択します。

「キーボード入力から変更」画面が表示されました。

キーボードの「変換」キーを押します。

「キーの変更」画面に戻ります。

「OK」ボタンを押します。

確認画面が表示されたら、「はい」を選択します。

「ATOKキーカスタマイズ」画面に戻ります。

「日本語入力ON」に「変換」キーが割り当てられました。

同様にして、「日本語入力OFF」に「無変換キー」を割り当てます。

以上で設定完了です。

快適な日本語入力を。

ReactでHello Worldする最速の手順

node.jsやbabel、webpackを導入しなくても、Reactできますよ。

ReactでHello Worldする

HTMLファイルを作ります。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
</body>
</html>

<head>~</head>に次のタグを追加して、reactのライブラリを読み込みます。

<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>

<body>~</body>に次のタグを追加します。

<div id="root"></div>

ここに、reactで作成した”Hello, world!”の文字を表示します。

最後に、JavaScriptのコードを記述します。

<script>
    ReactDOM.render(
        React.createElement('h1', {}, "Hello, world!"),
        document.getElementById('root')
    );
</script>

HTML全体は次のようになります。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
</head>
<body>
    <div id="root"></div>
    <script>
        ReactDOM.render(
            React.createElement('h1', {}, "Hello, world!"),
            document.getElementById('root')
        );
    </script>
</body>
</html>

ブラウザでHTMLファイルを開くと、”Hello, world!”の文字が表示されます。

JSXを使う

JSXを使う場合は、babelも必要になります。

<head>~</head>に次のタグを追加します。

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.23.1/babel.js"></script>

<script>~</script>を次のように書き換えます。
scriptタグのtype属性を忘れずに。

<script type="text/babel">
    ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('root') );
</script>

ブラウザでHTMLファイルを開くと、”Hello, world!”の文字が表示されます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.23.1/babel.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">
        ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('root') );
    </script>
</body>
</html>

この記事が役に立ったら、この本↓もおすすめです。

TypeScriptの–strictNullChecksでnullやundefinedの代入をチェックする

TypeScriptでは、すべての型の変数にnullやundefinedを代入できます。

let str: string = "Hello";
str = null; // OK
str = undefined; // OK

strictNullChecksモードを有効にすると、nullとundefinedはそれぞれの型とvoid以外の変数に代入できなくなります。

strictNullChecksモードを有効にします。

tsc index.ts --strictNullChecks

今度はstring型の変数にnullやundefinedを代入すると、エラーになります。

let str: string = "Hello";
str = null; // error TS2322: Type 'null' is not assignable to type 'string'.
str = undefined; // error TS2322: Type 'undefined' is not assignable to type 'string'.

strictNullChecksモードを有効にすることで、nullやundefinedによるエラーを減らすことができます。

TypeScriptでサーバーからファイルをダウンロードして、ローカルに保存するサンプルコード

TypeScriptでサーバーからファイルをダウンロードして、ローカルに保存するサンプルコード。

imagesディレクトリを作成して、ファイルを保存します。
ダウンロードするファイルと保存するファイルのファイル名は、download()関数の引数で設定します。

事前準備

npm install node-fetch --save
npm install @types/node-fetch --save

ソースコード

import * as fs from "fs";
import * as path from "path";
import fetch from "node-fetch";

// ダウンロードしたファイルを保存するディレクトリ
const download_dir = path.join(process.cwd(), "images");

// ディレクトリがなければ作成する
if (!fs.existsSync(download_dir)) {
    fs.mkdirSync(download_dir);
}

/**
* URLを受け取り、該当するファイルをダウンロードして保存する
* @param url ダウンロードするファイルのURL
* @param filename 保存するファイルのファイル名
*/
function download(url: string, filename: string) {
    fetch(url, { method: "GET" }).then((response) => {
        console.log(`OK: ${filename}`);
        response.body.pipe(fs.createWriteStream(filename));
    }).catch((error) => console.log(`error:${url} ${error}`));
};

download(
    "http://~/example.jpg",
    path.join(download_dir, "sample.jpg"));

TypeScriptでMap

Mapはキーと値の組み合わせを保持するコレクションです。

前準備

TypeScriptをインストールします。

npm install -g typescript
npm install -g typings

プロジェクトの初期設定を行います。

npm init
tsc --init
npm install tslint --save-dev
tslint --init

定義ファイルのインストール

npm install --save-dev @types/core-js

使用例

// Mapオブジェクトを生成する(キーと値の型はstring)
let map = new Map<string, string>();

// 値を追加する
map.set("key1", "value1");
map.set("key2", "value2");

// 要素の数
console.log(map.size); //=> 2

// キーから値を取得する
console.log(map.get("key1")); //=> value1
// キーが存在しないとき
console.log(map.get("hoge")); //=> undefined

// キーの一覧を取得する
console.log(map.keys()); //=> MapIterator { 'key1', 'key2' }

// 値の一覧を取得する
console.log(map.values()); //=> MapIterator { 'value1', 'value2' }

// キーと値の一覧を取得する
console.log(map.entries()); //=> MapIterator { [ 'key1', 'value1' ], [ 'key2', 'value2' ] }

// 反復処理
map.forEach(
    (value: string, key: string) => console.log(key + "=" + value)
);

console.log()を使うとTSLintが警告を出すとき

初期状態では、console.log()を使うとTSLintが警告を出します。

警告を無効にしたい場合は、tsconfig.jsonに”no-console”の設定を追加します。

{
    "extends": "tslint:recommended",
    "rules": {
        "no-console": [
            false
        ]
    }
}

TypeScriptでSet

Setは値が重複しないコレクションです。
同じ値は一つしか登録されません。

前準備

TypeScriptをインストールします。

npm install -g typescript
npm install -g typings

プロジェクトの初期設定を行います。

npm init
tsc --init
npm install tslint --save-dev
tslint --init

定義ファイルのインストール

npm install --save-dev @types/core-js

使用例

// オブジェクトを生成します
let set = new Set<string>(["node.js", "TypeScript"]);
// 値を追加します
set.add("JavaScript");
// 登録されている値の数
console.log(set.size); // => 3
// 値の有無
console.log(set.has("TypeScript")); // => true
// 値を削除する
set.delete("TypeScript");
// 値の有無
console.log(set.has("TypeScript")); // => false
// 値を順番に出力する
set.forEach((value) => console.log(value)); // => "node.js" "TypeScript"

Setオブジェクトを作成する

let set = new Set<string>();

引数で初期値を登録できます。

let set = new Set<string>(["node.js", "TypeScript"]);

値を追加する

addメソッドで値を登録します。

set.add("JavaScript");
set.add("Python");
set.add("C++");

値を削除する

deleteメソッドで値を削除します。

set.delete("Python");

値をクリアする

clearメソッドですべての値を削除します。

set.clear();

値に対して関数を実行する

forEachメソッドで値に対して関数を実行します。

set.forEach(value => console.log(value));

値の有無を調べる

let exist = set.has("TypeScript");

Iteratorを取得する

keysメソッドとvaluesメソッドは、どちらも値を登録した順番を保持するIteratorオブジェクトを返します。

console.log(set.keys());
//=> SetIterator { 'node.js', 'TypeScript', 'JavaScript' }

iterable

Setはiterableです。

Array.from()はiterableを受け取り、Arrayオブジェクトを生成します。

let ary = Array.from(set);