株式会社シーポイントラボ | 浜松のシステム・RTK-GNSS開発

【TypeScript】インターフェース満たしているか判断する機能を作る

 TypeScriptはJavaScriptの拡張言語です。そのため他の型を明記することを前提とした言語によくある機能が存在しないことがままあります。使いたいのはPHPでいう次のようなものです。

<?php
interface Hoge{}
class A implements Hoge {}
class B {}

$a = new A();
var_dump($a instanceof Hoge);// true

$b = new B(); 
var_dump($b instanceof Hoge);// false

 instanceofはクラスあるいはインターフェースを満たしていたらtrue, 満たしていなければfalseとなる演算子です。
PHP: 型演算子 – Manual
 JavaScriptでも同じ目的の構文があります。

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// expected output: true

console.log(auto instanceof Object);
// expected output: true

instanceof – JavaScript | MDN
 残念ながらTypeScriptのinstanceof演算子はTypeScriptで作れる型やインターフェース拡張をカバーしていません(少なくともバージョン3.6.xでは)。自分で作る必要があります。 auto instanceof CarInterface の様に右側にインターフェースを持ってきた場合、エラーが起きます。
 実現するコードは次です。

interface LatLngLiteral {
  lat: number;
  lng: number;
}
/**
 * 引数がLatLngLiteralを満たしているか識別
 */
function implementsLatLngLiteral(arg: any): arg is LatLngLiteral {
  return arg !== null
        && typeof arg === 'object'
        && typeof arg.lat === 'number'
        && typeof arg.lng === 'number';
}
// const latLng = {lat: 35, lng: 137};
// const latLng = 'hoge';
if(implementsLatLngLiteral(latLng)){
  console.log('LatLngLiteralを満たしています')
} else {
  console.log('LatLngLiteralを満たしていません')
}

 識別用の関数を作り、インターフェースを満たしているかプロパティを一つ一つチェックしていき、最終的にチェック結果の真偽値を返します。加えてこの真偽値の意味を”引数 is 型”(上の例ならば arg is LatLngLiteral)でTypeScriptに示します(ただbooleanとするとインターフェースを満たしていることをTypeScriptが識別してくれない)。
 このやり方は一つのやり方であり、他の方法やより深いことは次のガイドが詳しいです。
Type Guard – TypeScript Deep Dive 日本語版

  • この記事いいね! (0)