TypeScriptの`window`に新しいプロパティを明示的に設定するにはどうすればよいですか?
-
13-12-2019 - |
質問
プロパティを明示的に設定して、オブジェクトのグローバル名前空間を設定します window
.
window.MyNamespace = window.MyNamespace || {};
TypeScriptの下線 MyNamespace
と文句を言うこと:
プロパティ'MyNamespace'は'window'型の値に存在しません 任意の"
宣言することでコードを機能させることができます MyNamespace
アンビエント変数とドロップするようにして、 window
明示的ですが、私はそれをしたくありません。
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
どのように私は保つことができますか window
そこにTypeScriptを幸せにしますか?
サイドノートとして、TypeScriptがそれを教えてくれるので、TypeScriptが文句を言うのは特に面白いと思います window
タイプのものです any
これは間違いなく何かを含めることができます。
解決
ちょうどこれに対する答えを見つけました 別のStackOverflowの質問の答え.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
基本的には、既存のものを拡張する必要があります window
あなたの新しいプロパティについてそれを伝えるためのインターフェイス。
他のヒント
動的に保つには、次のようにします:
(<any>window).MyNamespace
TYPESCRIPT^3.4.3以降、このソリューションは機能しなくなりました
または。..
あなただけの入力することができます:
window['MyNamespace']
そして、あなたはコンパイルエラーを得ることはありませんし、それはタイピングと同じように動作します window.MyNamespace
TSXを使用していますか?他の答えはどれも私のために働いていませんでした。
ここに私がしたことがあります:
(window as any).MyNamespace
受け入れられた答えは、私が使用していたものですが、TypeScript0.9では使用されていました。*それはもはや動作しません。の新しい定義 Window
インターフェイスは、組み込み定義を拡張するのではなく、組み込み定義を完全に置き換えるようです。
私は代わりにこれを行うことにしました:
interface MyWindow extends Window {
myFunction(): void;
}
declare var window: MyWindow;
更新: TypeScript0.9.5では、受け入れられた答えが再び機能しています。
グローバルは「悪」です:)、移植性も持っている最良の方法は次のとおりだと思います:
まず、インターフェイスをエクスポートします:(例::./カスタム。ウィンドウ。ts)
export interface CustomWindow extends Window {
customAttribute: any;
}
二番目にインポートします
import {CustomWindow} from './custom.window.ts';
CustomWindowを使用した第三のキャストグローバルvarウィンドウ
declare let window: CustomWindow;
このようにして、ウィンドウオブジェクトの既存の属性で使用する場合、別のIDEに赤い線もないので、最後に試してみてください:
window.customAttribute = 'works';
window.location.href = '/works';
Typescript2.4でテストされました。xと最新!
拡張する必要がある場合 window
の使用を必要とするカスタム型を持つオブジェクト import
次の方法を使用できます:
ウィンドウ。d.ts
import MyInterface from './MyInterface';
declare global {
interface Window {
propName: MyInterface
}
}
ハンドブックの"宣言のマージ"セクションの"グローバル拡張"を参照してください: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
私はこれを頻繁に行う必要はありません、私が持っていた唯一のケースはミドルウェアでRedux Devtoolsを使用するときでした。
私は単にしました:
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
またはあなたが行うことができます:
let myWindow = window as any;
そして myWindow.myProp = 'my value';
を使用している人のために Angular CLI それは簡単です:
-----------ts
declare global {
interface Window {
myCustomFn: () => void;
}
}
私のカスタムutils。ts
window.myCustomFn = function () {
...
};
IntelliJを使用している場合は、新しいポリフィルを取得する前にIDEで次の設定を変更する必要もありました:
> File
> Settings
> Languages & Frameworks
> TypeScript
> check 'Use TypeScript Service'.
他の答えのほとんどは完璧ではありません。
- それらのうちのいくつかは、shopの型推論を抑制するだけです。
- 他のいくつかは、名前空間としてのグローバル変数のみを気にしますが、インターフェイス/クラスとしては気にしません
私は今朝も同様の問題に遭遇しました。私はSOで非常に多くの「解決策」を試しましたが、それらのどれも絶対に型エラーを生成せず、IDE(webstormまたはvscode)で型ジャンプをトリガーできるようにしました。
最後に、ここから
https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512
, 、私は合理的な解決策を見つける インターフェイス/クラスと名前空間の両方として機能するグローバル変数のタイピングを添付します.
例は以下の通りです:
// typings.d.ts
declare interface Window {
myNamespace?: MyNamespace & typeof MyNamespace
}
declare interface MyNamespace {
somemethod?()
}
declare namespace MyNamespace {
// ...
}
ここで、上記のコードはnamespaceの型をマージします MyNamespace
とインターフェイス MyNamespace
グローバル変数に myNamespace
(ウィンドウのプロパティ)。
周りの答えを見つけた後、私はこのページが役に立つかもしれないと思います。https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation 宣言のマージの歴史についてはわかりませんが、なぜ以下が機能するのかを説明しています。
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
あなたが使用している場合、それを行う方法は次のとおりです TypeScript定義マネージャ!
npm install typings --global
作成 typings/custom/window.d.ts
:
interface Window {
MyNamespace: any;
}
declare var window: Window;
カスタムタイピングをインストールする:
typings install file:typings/custom/window.d.ts --save --global
終わった、それを使用してください! Typescriptはもう文句を言わない:
window.MyNamespace = window.MyNamespace || {};
Typescript3を使用している場合。xでは、省略できる場合があります declare global
他の答えに参加し、代わりに使用するだけです:
interface Window {
someValue: string
another: boolean
}
これは、Typescript3.3、WebPack、およびTSLintを使用するときに私と一緒に機能しました。
Typscriptは文字列プロパティに対して型チェックを実行しません。
window["newProperty"] = customObj;
理想的には、グローバル変数のシナリオは避けるべきです。ブラウザコンソールでオブジェクトをデバッグするために時々使用します。
参考までに(これが正解です):
Aの中 .d.ts
定義ファイル
type MyGlobalFunctionType = (name: string) => void
ブラウザで作業している場合, メンバーをブラウザのウィンドウコンテキストに追加するには、ウィンドウのインターフェイスを再度開きます:
interface Window {
myGlobalFunction: MyGlobalFunctionType
}
NodeJSのための同じ考え:
declare module NodeJS {
interface Global {
myGlobalFunction: MyGlobalFunctionType
}
}
これで、ルート変数を宣言します(実際にはウィンドウまたはグローバルに存在します)
declare const myGlobalFunction: MyGlobalFunctionType;
その後、定期的に .ts
ファイルが、副作用としてインポートされ、あなたは実際にそれを実装します:
global/* or window */.myGlobalFunction = function (name: string) {
console.log("Hey !", name);
};
そして最後に、コードベースの他の場所でそれを使用します:
global/* or window */.myGlobalFunction("Kevin");
myGlobalFunction("Kevin");
カスタムインターフェイスを作成してウィンドウを拡張し、カスタムプロパティをオプションとして追加します。
次に、カスタムインターフェイスを使用するが、元のウィンドウで評価されるcustomWindowを許可します。
それはで働いていますtypescript@3.1.3...
interface ICustomWindow extends Window {
MyNamespace?: any
}
const customWindow:ICustomWindow = window;
customWindow.MyNamespace = customWindow.MyNamespace {}
に計算されたプロパティまたは動的プロパティを設定したい人のために window
オブジェクト、あなたはそれが不可能であることがわかります declare global
メソッド。このユースケースを明確にするには
window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature
あなたはこのようなことをしようとするかもしれません
declare global {
interface Window {
[DyanmicObject.key]: string; // error RIP
}
}
ただし、上記はエラーになります。これは、Typescriptでは、インターフェイスが計算されたプロパティでうまく機能せず、次のようなエラーをスローするためです
A computed property name in an interface must directly refer to a built-in symbol
これを回避するには、キャストの提案に行くことができます window
に <any>
だからあなたはすることができます
(window as any)[DynamicObject.key]
私は今日Angular(6)ライブラリでこれを使用したかったので、これを期待どおりに動作させるにはしばらく時間がかかりました。
私のライブラリが宣言を使用するためには、私は使用しなければなりませんでした d.ts
グローバルオブジェクトの新しいプロパティを宣言するファイルの拡張子。
だから最後に、ファイルは次のようなものになってしまいました:
/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts
作成したら、それをあなたの中に公開することを忘れないでください public_api.ts
.
それは私のためにそれをしました。これが役立つことを願っています。
まず、現在のスコープでwindowオブジェクトを宣言する必要があります。
Typescriptはオブジェクトのタイプを知りたいからです。
ウィンドウオブジェクトは別の場所で定義されているため、再定義することはできません。
ただし、次のように宣言できます:-
declare var window: any;
これはwindowオブジェクトを再定義したり、名前を持つ別の変数を作成したりしません window
.
これは、windowが別の場所で定義されており、現在のスコープで参照しているだけであることを意味します。
次に、MyNamespaceオブジェクトを簡単に参照できます:-
window.MyNamespace
または、新しいプロパティを次のように設定できます window
単純にオブジェクト:-
window.MyNamespace = MyObject
そして今、typescriptは文句を言わないでしょう。