水無瀬のプログラミング日記

プログラムの勉強した時のメモ

TypeScript(Javascript)の型判定まとめ

TL;DR.

TypeScript(javascript)で配列の型を調べる時は要注意。
IE滅ぶべし。
今回のソース

はじめに

ある日偉い人は言いました。
「これ、IEで動かしたいんだけど。」
運良く特に苦労も困りもしなかったけど、TS(JS)の型について改めて調べ直したから軽くまとめる。

型を調べる方法(前座)

typeof hogeで調べる事ができる。
結果はコメントの通り。

const string = '';
const number = 0;
const boolean = true;
const nul = null;
const object = {};
const symbol = Symbol('hoge');
let a;

console.log(`string: ${typeof string}`); // string
console.log(`number: ${typeof number}`); // number
console.log(`boolean: ${typeof boolean}`); // boolean
console.log(`nul: ${typeof nul}`); // object
console.log(`symbol: ${typeof symbol}`); // symbol
console.log(`a: ${typeof a}`); // undefined
console.log(`object: ${typeof object}`); // object

ちなみにjavascriptに用意されている型は'object'と下記6個。

  • string
  • number
  • boolean
  • null
  • symbol
  • undefined

nullがnullじゃない罠。
ちゃんと見たければ下記のようにする。
結果は[object hoge]の様になる。
これで基本的には型がちゃんと分かるはず。

const string = '';
const number = 0;
const boolean = true;
const nul = null;
const object = {};
const symbol = Symbol('hoge');
let a;

console.log(`string: ${Object.prototype.toString.call(string)}`); // [object String]
console.log(`number: ${Object.prototype.toString.call(number)}`); // [object Number]
console.log(`boolean: ${Object.prototype.toString.call(boolean)}`); // [object Boolean]
console.log(`nul: ${Object.prototype.toString.call(nul)}`); // [object Null]
console.log(`symbol: ${Object.prototype.toString.call(symbol)}`); // [object Symbol]
console.log(`a: ${Object.prototype.toString.call(undefined)}`); // [object Undefined]
console.log(`object: ${Object.prototype.toString.call(object)}`); // [object Object]

前座その2(配列編)

本編の前に最後の前座。
配列の場合はどうなるのよという話。
typeofではダメ。Object.prototype.toString.call()でようやく配列だとわかる。
ちなみに配列か知りたいかどうかならArray.isArray()を使えば困らない。

const arrayString = new Array<string>();
const arrayNumber = new Array<number>();
const arrayObject = new Array<object>();

console.log(`arrayString:${typeof arrayString}`); // object
console.log(`arrayNumber:${typeof arrayNumber}`); // object
console.log(`arrayObject:${typeof arrayObject}`); // object
console.log(`arrayString:${Object.prototype.toString.call(arrayString)}`); // [object Array]
console.log(`arrayNumber:${Object.prototype.toString.call(arrayNumber)}`); // [object Array]
console.log(`arrayObject:${Object.prototype.toString.call(arrayObject)}`); // [object Array]

本編

で、今回困ったことは上記とは全く関係ない。
配列に特定の要素が含まれているか判定するのにArray.includesというものがある。

const array = [1, 3, 5];
console.log(`array has 3 ? ${array.includes(3)}`); // true
console.log(`array has 4 ? ${array.includes(4)}`); // false

実はこの関数がIEで動かない。IE11でも動かない。
これが困ったこと。
以下、今回やった解決策。

const array = [1, 3, 5];

/**
 * Array.includes()の代替
 * @param array 検索される配列
 * @param target 検索対象
 */
const arrayIncludes = (array: any[], target: any ) => {
    // 配列無いならリターン
    if (array == null) {
        return false;
    }
    // 配列をループし、一致するものがあれば終了
    return array.some(item => {
        return item === target;
    });
}

console.log(`array has 3 ? ${arrayIncludes(array, 3)}`); // true
console.log(`array has 4 ? ${arrayIncludes(array, 4)}`); // false

その他代替案

普通は下記のようにするのかも?

const array = [1, 3, 5];

// 見つかればindex.見つからなければ-1を返す。
if (array.indexOf(3) != 0) {
    console.log('array has 3');
}

なんで型の話をしたか

型が違うときにループする前にリターンしたいとか考えていたから。
記事書きなら思ったけど、別にtrueになることは無いから気にしなくて良い気がしてきた。

まとめ

javascriptの型判定は意外とめんどくさい。
IEは滅んでほしい。

参考