TypeScript 拡張メソッドを使ってみた

JavaScriptで文字列をすべて小文字にするときには、.toLowerCase()を使いますが、同じような感じで、”文字列”.method()のようにしたかったのでしらべてみました。

本当に拡張メソッドと呼ぶのかわかりませんが、c#で拡張メソッドと呼んでましたので拡張メソッドとします。

JavaScriptでのやりかた

JavaScriptではprototypeを使って簡単に作成できます。文字列にたいして、引数の文字列を加えて返すメソッドをつくると

String.prototype.add = function(str:string){
  return this + str;
}
console.log("abc".add("dcefg").add("12345")); 
//abcdcefg12345

TypeScriptでのやりかた

export { }

declare global {
  interface String {
    add(a:string):string;
  }
}

String.prototype.add = function(str:string){
  return this + str;
}

decleare globalの後にinterfaceで型式を宣言する必要があります。前に別の変数やメソッドでexportを宣言していれば、export { } は不要です。

別のファイルでの呼び出し方

import "./filename";
console.log("abc".add("dcefg").add("12345"));
//abcdcefg12345

実装

これを踏まえて全角を半角にするメソッドを実装。method(“文字列”)みたいな形でも使いたかったので、オーバーロードも試してみました。

試しに作成したのは、全角英数字と全角スペースを半角に変換するメソッドです。英数字とスペースは別々に作成し、一つにまとめました。

まずは、普通にメソッドを作成

/** 全角英数字を半角に変換 */
function zenkaku2hankaku_alphameric(str: string): string {
    return str.replace(/[A-Za-z0-9]/g, function (s) {
        return String.fromCharCode(s.charCodeAt(0) - 0xfee0);
    });
}
/** 全角スペースを半角スペースに変換 */
function zenkaku2hankaku_space(str: string) {
    return str.replace(/ /g, function (s) {
        return String.fromCharCode(s.charCodeAt(0) - 0x2fe0);
    });
}
/** 全角英数字とスペースを半角に変換 */
export function zenkaku2hankaku(str: string): string {
    return zenkaku2hankaku_space(zenkaku2hankaku_alphameric(str));
}

拡張メソッドの部分

declare global {
    interface String {
        zenkaku2hankaku(): string;
    }
}
String.prototype.zenkaku2hankaku = function () {
    return zenkaku2hankaku(this.toString());
}

thisだけだと下記のような理由でコンパイルが通りませんでした。

this: String 
Allows manipulation and formatting of text strings and determination and location of substrings within strings. 
型 'String' の引数を型 'string' のパラメーターに割り当てることはできません。 
'string' はプリミティブですが、'String' はラッパー オブジェクトです。できれば 'string' をご使用ください

プリミティブのstringとStringオブジェクトで区別されます。this.toString()でプリミティブへ変換することができます。

TypeScriptでは記入している段階で違うことがわかるので素晴らしいです。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です