web-dev-qa-db-ja.com

TypeScript(システム)の拡張メソッド

私のangular2プロジェクトでは、TypeScriptを使用してstringクラスのプロトタイプを拡張しようとしています。これは私のコードです:

interface String 
{
    startsWith(s:string);
    contains(s:string);
    containsOr(s1:string, s2:string);
}

String.prototype.startsWith = function (s:string):boolean {
    return this.indexOf (s) === 0;
}
String.prototype.contains = function (s:string):boolean {
    return this.indexOf(s) > 1;
}
String.prototype.containsOr = function (s1:string, s2:string):boolean {
    return this.indexOf(s1) > 1 || this.indexOf (s2) > 1;
}

このコードを使用すると、プロジェクトはコンパイルされます(Visual Studio Codeのコンテンツアシストも私を支援します)が、実行時に「contains is not defined」が表示されます。

私は何を間違っていますか?

どうもありがとう

PS:これは私のtsconfigです:

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "outDir": "wwwroot/app/source/"
  },
  "exclude": [
    "node_modules",
    "bower_components",
    "wwwroot",
    "typings/main",
    "typings/main.d.ts"
  ]
}

[〜#〜]編集[〜#〜]

jsファイルをindex.htmlにインポートすると機能することに気付きました、しかし、私はこのアプローチが好きではありません。

<script src="app/source/utils/extensions.js"></script>
16
user3471528

TSエラーなし(1.8.9)、Angular2(2.0.0-beta.12)エラーなしで機能し、次のテンプレートを使用して関数呼び出しを機能させることができました。

tsconfig.json

{
  "compilerOptions": {
  "target": "es5",
  "module": "system",
  "moduleResolution": "node",
  "sourceMap": true,
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  "removeComments": false,
  "noImplicitAny": false
},
"exclude": [
  "node_modules",
  "typings/main",
  "typings/main.d.ts"
  ]
}

次に、プロジェクトにローカルなglobal.d.tsファイルを作成します(存在しない場合)。

global.d.ts(プロジェクトのローカル、同じ名前のメインTSファイルではない)

export {}

   declare global {
     interface String {
       calcWidth(): number;
     }
   }

extensions.ts(ファイル全体)

export {}

//don't redefine if it's already there
if (!String.prototype.hasOwnProperty('calcWidth')) {
    String.prototype.calcWidth = function (): number {
      //width calculations go here, but for brevity just return length
      return this.length;
    }
}

次に、あなたの最初のSystem.import(filename)は(mine is main.ts)です。一度だけ使用:

import './extensions'  //or whatever path is appropriate
... 
...

これで、アプリ全体でインターフェースを使用できます。

var testString = 'fun test';
console.log(testString.calcWidth());

コンソール出力を生成します:

8

これがお役に立てば幸いです。

18
Paul M

コードをHTMLでインポートする代わりに、これをコードの先頭に配置するだけです。

import './utils/extensions';

それをファイルへのパスに置き換えるだけです。

モジュールとインポートに関するその他のリソースを次に示します。

TypeScript docs

MDNドキュメント

1
Luka Jacobowitz