0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TypeScriptでちょっと便利かもしれない拡張メソッドを書いてみたので見てほしい

Posted at
const hoge : string = 'hoge';

if(hoge === 'fuga' || hoge === '(「・ω・)「がおー'){
  return true;
}
else{
  return false;
}

みたいに、

比較対象(今回はString)がいずれかの候補と同じものであればtrue
そうでなければfalseを返す

こういうケース、そんなに多くないけど実際書くと面倒くさいよね
(この例は最悪なもので、普通なら候補を Array に突っ込んで map で順に比較みたいなのが多いと勝手に思う)

本記事では、このめんどくさいを解決する拡張メソッドを深夜テンションで書いてみた話をお送りいたします。

メソッド命名から入ってみる

私は残念なことに英語を雰囲気で読むくらいしかできないので命名はGoogle先生に頼ることにしました
Screen Shot 2020-02-23 at 3.31.25.png

ながったらしい。 結局少し考えて.anyIn()で行くことで決めた。ソッチのほうが自然そう。

メソッドの仕様

'hoge'.anyIn('fuga', 'hoge'); // => true
'fuga'.anyIn('f')             // => false

だいたいこんな感じの記述デザインにしてみた。可変長引数を使えば実装も難しくはなさげ

実装

こちらのサイトを参考にさせていただきました。
https://kakkoyakakko2.hatenablog.com/entry/2018/06/12/003000

string_extention.ts
// これないとエラーが出る
export {};

declare global {
  interface String {
    /**
     * 引数のStringと呼び出し元のStringをORで比較して  
     * どれかと等しければ `true` でなければ `false`
     * @param word string 1つ目(**require param**)
     * @param args string 2つ目以降(option)
     */
    anyIn(word : string, ...args: Array<string>): boolean;
  }
}

// ここはArrow Functionにしてはいけない(後述)
String.prototype['anyIn'] = function(word: string, ...args: Array<string>) : boolean{
  if(this === word){
    return true;
  }
  else{
    // ここからはもうちょっと楽にかけたかも
    let result : boolean = false;
    args.forEach((char) => {
      if(this === char){
        result = true;
      }
    });
    return result;
  }
};

...は可変長引数の宣言をしているだけ。使用する際2つ目以降の引数が順番にArrayに突っ込まれる。
あとはJSでの拡張定義に型の注釈が増えたくらい。

あとは使うタイミングで import してやればStringにぶら下がるメソッドとして使用可能。

main.ts
import './string_extention';

console.log('hoge'.anyIn('ho', 'hoge')); // => true 

VSCodeでもJSDocが出てくる。
Screen Shot 2020-02-23 at 3.51.26.png

ArrowFunctionについて気をつけること

ほぼほぼのFunction定義は() =>で書けるが、今回のケースでは呼び出し元をthisで拾えることが前提となる。('hoge'.anyIn()の中で'hoge'を拾えるようにする)
ここで気をつけないといけないのが、Arrow Functionにおけるthisの束縛について。

MDNのドキュメントには以下のように記述されている

アロー関数式は、より短く記述できる、通常の function 式の代替構文です。また、this, arguments, super, new.target を束縛しません。

どういうこっちゃ?🤔
まあ言いたいことはぶっちゃけmejileben氏の記事で解説されているので要約すると

  • function()ではthisを実行する段階で確定している。
  • それに対し() =>thisは宣言の段階で確定している。
  • そのためレシーバを拾う必要のあるメソッドはfunction()で定義する
  • 今回の場合'hoge'.anyIn()で書きたいのでArrow Functionは使えない

という感じ

まとめ

  • 意外と簡単に拡張メソッドを作れる あと書いていて気持ちいい命名になったかも
  • Arrow Functionは楽に書けるし視認性も上がるのでほぼ置き換えても良い。
    • 今回のように例外となるケースもあることは理解しておくこと。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?