質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

8469閲覧

TypeScriptで外部モジュールに拡張メソッドを追加したい

ueda.kojiro

総合スコア10

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

1クリップ

投稿2017/06/04 05:22

編集2017/06/05 03:33

前提・実現したいこと

TypeScriptを使って開発を行っています。
Protractorが公開しているクラスElementFinderに対してメソッドを追加したいと考えています。
JavaScriptでいうと、以下のような感じです。

js:sample.js

1var ElementFinder = require( "protractor" ).ElementFinder; 2ElementFinder.prototype.additionalFunc = function() { 3 // do something 4}

試したこと

そこで、こちらModule Augumentationを参考に以下のようなコードを書いてみましたが、TSLintで怒られ、ビルドも通りません。

ts:sample.ts

1declare module 'protractor' { 2 interface ElementFinder { 3 additionalFunc(); 4 } 5} 6 7ElementFinder.prototype. additionalFunc = function() { 8 // do something 9};

発生している問題・エラーメッセージ

shell

1[ts] 'ElementFinder' only refers to a type, but is being used as a value here.

伺いたいこと

  • このような記法はTypeScriptにはできないのでしょうか?

補足

バージョンはそれぞれ以下の通りです。

"ntypescript": "1.201609302242.1", "tslint": "5.4.2", "typescript": "2.3.4"

実際の解決方法

ベストアンサーとさせていただいた方法をもとに実際に対応した内容は以下の通りです。
本来ならば、ベストアンサーの回答に記載すべきところですが、MarkDown記法が利用できなかったため、こちらに記載させていただきます。

wrapper.ts

1(<any>ElementFinder).prototype.additionalFunc = function() { 2 // do something. 3} 4export class WrappedElementFinder extends ElementFinder { 5 additionalFunc() { 6 // どうせこれは呼ばれないので、適当に実装する 7 return <any>null; 8 } 9} 10export function elementWrapper(): WrappedElementFinder { 11 // protractor.elementというメソッドがElementFinderを生成して返す。 12 return <WrappedElementFinder>protractor.element(); 13}

test.ts

1import { elementWrapper } from wrapper.ts 2var finder = elementWrapper(); 3finder.additionalFunc(); // 「メソッドがない」と怒られない

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

TypeScriptはJavaScriptを静的言語として扱うため、後からの定義の変更はできなかったと思います。逆に言うと変更されないことをある程度保証しているとも言います。<any>でキャストしてany型にしてしまえば何でも扱えるようになりますが、TypeScriptの利点を消してしまっています。

TypeScript

1(<any>ElementFinder).prototype.additionalFunc = function() { 2 // do something 3}; 4 5var ef = <any>new ElementFinder; 6ef.additionalFunc();

素直に作るのであれば、ElementFinderを継承した別のクラスを作ることです。

TypeScript

1class ElementFinderAdded extends ElementFinder { 2 additionalFunc() { 3 // do something 4 } 5}

投稿2017/06/04 21:41

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ueda.kojiro

2017/06/05 03:05 編集

ありがとうございます! アドバイスいただいた方法で対応できました。 `ElementFinder`を`new`するのは、`Protractor`というツールであるため、新たなクラスを作成するというだけではうまくいかず、キャストとの複合で対応することになりました。 実装がきれいではないのは重々承知しているのですが、これで`TypeScript`の恩恵を受けることができるようになってうれしいです。 ありがとうございました! 具体的には以下のように対応しました。 ```wrapper.ts (<any>ElementFinder).prototype.additionalFunc = function() { // do something. } export class WrappedElementFinder extends ElementFinder { additionalFunc() { // どうせこれは呼ばれないので、適当に実装する return <any>null; } } export function elementWrapper(): WrappedElementFinder { // protractor.elementというメソッドがElementFinderを生成して返す。 return <WrappedElementFinder>protractor.element(); } ``` ```test.ts import { elementWrapper } from wrapper.ts var finder = elementWrapper(); finder.additionalFunc(); // 「メソッドがない」と怒られない ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問