Comment vous définissez explicitement une nouvelle propriété sur `window` dactylographiée?

voix
247

Je configuration des espaces de noms global pour mes objets en définissant explicitement une propriété sur window.

window.MyNamespace = window.MyNamespace || {};

Tapuscrit souligne MyNamespaceet se plaint que:

La propriété « MyNamespace » n'existe pas sur la valeur de type « fenêtre » tout »

Je peux faire le travail de code en déclarant MyNamespacecomme une variable ambiante et laisser tomber le windowexplicitation mais je ne veux pas faire cela.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Comment puis - je garder windowlà - bas et faire tapuscrit heureux?

Comme une note de côté , je trouve particulièrement drôle que tapuscrit se plaint car il me dit que windowest de type anyqui , par certainement peut contenir quoi que ce soit.

Créé 03/10/2012 à 14:01
source utilisateur
Dans d'autres langues...                            


19 réponses

voix
253

Pour garder dynamique, il suffit d'utiliser:

(<any>window).MyNamespace
Créé 09/06/2015 à 19:18
source utilisateur

voix
235

Je viens de trouver la réponse à cela dans la réponse d' une autre question StackOverflow .

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};

Fondamentalement , vous devez étendre l'existant windowinterface pour lui dire au sujet de votre nouvelle propriété.

Créé 03/10/2012 à 14:46
source utilisateur

voix
127

Ou...

vous pouvez simplement taper:

window['MyNamespace']

et vous obtiendrez pas une erreur de compilation et fonctionne de la même chose que taper window.MyNamespace

Créé 20/11/2012 à 20:36
source utilisateur

voix
84

En utilisant TSX? Aucun des autres réponses travaillaient pour moi.

Voici ce que je l'ai fait:

(window as any).MyNamespace
Créé 15/08/2016 à 23:25
source utilisateur

voix
46

La réponse acceptée est ce que je l' habitude d'utiliser, mais avec 0,9 tapuscrit. * Il ne fonctionne plus. La nouvelle définition de l' Windowinterface de semble remplacer complètement la définition intégrée, au lieu de l' augmenter.

Je l'ai pris à le faire à la place:

interface MyWindow extends Window {
    myFunction(): void;
}

declare var window: MyWindow;

MISE À JOUR: Avec tapuscrit 0.9.5 la réponse acceptée fonctionne à nouveau.

Créé 27/08/2013 à 22:22
source utilisateur

voix
29

Si vous avez besoin d'étendre l' windowobjet avec un type personnalisé qui nécessite l'utilisation de importvous pouvez utiliser la méthode suivante:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Voir dans la section « Déclaration de fusion » « Global Augmentation » du Manuel: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

Créé 23/10/2016 à 15:24
source utilisateur

voix
19

Mondial sont :) « mal », je pense que la meilleure façon d'avoir aussi la portabilité est:

Tout d'abord exporter l'interface: (par exemple: ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Deuxième importation

import {CustomWindow} from './custom.window.ts';

Troisième fenêtre fonte globale var avec CustomWindow

declare let window: CustomWindow;

De cette façon, vous n'avez pas aussi ligne rouge dans différents IDE si vous utilisez des attributs existants de l'objet de la fenêtre, donc à l'essai final:

window.customAttribute = 'works';
window.location.href = '/works';

Testé avec Tapuscrit 2.4.x

Créé 27/07/2017 à 13:28
source utilisateur

voix
8

Voici comment le faire, si vous utilisez tapuscrit Gestionnaire de définitions !

npm install typings --global

Créer typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Installez votre saisie personnalisée:

typings install file:typings/custom/window.d.ts --save --global

Fait, utilisez - le ! Tapuscrit ne se plaindra plus:

window.MyNamespace = window.MyNamespace || {};
Créé 19/11/2016 à 21:31
source utilisateur

voix
7

Je ne ai pas besoin de le faire très souvent, le seul cas que j'ai eu était lors de l'utilisation Redux Devtools avec middleware.

Je l'ai fait tout simplement:

const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

Ou vous pourriez faire:

let myWindow = window as any;

et alors myWindow.myProp = 'my value';

Créé 06/06/2018 à 13:13
source utilisateur

voix
5

La plupart des autres réponses ne sont pas parfaits.

  • Certains d'entre eux suppriment juste l'inférence de type pour un magasin.
  • Certains des autres ne se soucie de variable globale comme espace de noms, mais pas d'interface / classe

Je rencontre aussi le même problème ce matin. J'ai essayé tant de « solutions » sur le SO, mais aucun d'entre eux ne produisent aucune erreur de type tout à fait et activer le déclenchement de saut de type dans IDE (WebStorm ou vscode).

Enfin, d'ici

https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

, Je trouve une solution raisonnable de fixer typages pour variable globale qui agit comme une interface / classe et espace de noms à la fois .

L'exemple est ci-dessous:

// typings.d.ts
declare interface Window {
    myNamespace?: MyNamespace & typeof MyNamespace
}

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Maintenant, le code se confond au- dessus des typages de l' espace de noms MyNamespaceet de l' interface MyNamespacedans la variable globale myNamespace(la propriété de la fenêtre).

Créé 19/05/2017 à 03:26
source utilisateur

voix
5

Si vous utilisez la CLI angulaire , il est vraiment simple (testé sur CLI RC.0):

src / polyfills.ts

declare global {
  interface Window {
    myCustomFn: () => void;
  }
}

my-mesure-utils.ts

window.myCustomFn = function () {
  ...
};

J'utilise IntelliJ, donc j'ai aussi besoin de changer le paramètre suivant dans l'IDE avant mes nouvelles polyfills ramassé:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
Créé 21/03/2017 à 13:38
source utilisateur

voix
2

Pour ceux qui veulent définir une propriété calculée ou dynamique sur l' windowobjet, vous constaterez que pas possible avec la declare globalméthode. Pour clarifier pour ce cas d'utilisation

window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature

Vous pourriez essayer de faire quelque chose comme ça

declare global {
  interface Window {
    [DyanmicObject.key]: string; // error RIP
  }
}

Ce qui précède l'erreur cependant. En effet, dans Tapuscrit, les interfaces ne jouent pas bien avec les propriétés calculées et jetteront une erreur comme

A computed property name in an interface must directly refer to a built-in symbol

Pour contourner ce problème, vous pouvez aller avec le suggérer de jeter windowà <any>vous pouvez donc faire

(window as any)[DynamicObject.key]
Créé 13/02/2019 à 00:15
source utilisateur

voix
2

Faites une interface personnalisée étend la fenêtre et ajoutez votre propriété personnalisée en option.

Ensuite, laissez le customWindow qui utilisent l'interface personnalisée, mais avec une valeur la fenêtre d'origine.

Il a travaillé avec le typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
Créé 12/11/2018 à 07:29
source utilisateur

voix
2

Je voulais l'utiliser dans une bibliothèque aujourd'hui angulaire (6) et il m'a fallu un certain temps pour que cela fonctionne comme prévu.

Pour ma bibliothèque à utiliser des déclarations que je devais utiliser le d.tsextention pour le fichier qui déclare les nouvelles propriétés de l'objet global.

Donc à la fin, le fichier a fini avec quelque chose comme:

/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts

Une fois créé, ne pas oublier de l' exposer dans votre public_api.ts.

Cela a fait pour moi. J'espère que cela t'aides.

Créé 01/08/2018 à 11:29
source utilisateur

voix
2

Pour référence (ce qui est la bonne réponse):

A l' intérieur d' un .d.tsfichier de définition

type MyGlobalFunctionType = (name: string) => void

Si vous travaillez dans le navigateur, vous ajoutez des membres au contexte de la fenêtre du navigateur en rouvrant l'interface de la fenêtre:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Même idée pour NodeJS:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}

Maintenant, vous déclarez la variable racine (qui fait vivre la fenêtre ou mondiale)

declare const myGlobalFunction: MyGlobalFunctionType;

Puis , dans un régulier .tsfichier, mais comme importé effet secondaire, vous implémentez réellement:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};

Et enfin l'utiliser ailleurs dans le code de base, soit:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");
Créé 20/04/2017 à 15:50
source utilisateur

voix
1

Si vous utilisez 3.x dactylographiée, vous pourrez peut - être omettre la declare globalpartie dans les autres réponses et au lieu simplement utiliser:

interface Window {
  someValue: string
  another: boolean
}

Cela a fonctionné avec moi lors de l'utilisation Tapuscrit 3.3, WebPack et TSLint.

Créé 12/02/2019 à 21:50
source utilisateur

voix
0

TYPESCRIPT ne fonctionne pas typecheck sur les propriétés de chaîne.

window["newProperty"] = customObj;

Idéalement, le scénario variable globale devrait éviter. Je l'utilise parfois pour déboguer un objet dans la console du navigateur.

Créé 18/06/2019 à 22:01
source utilisateur

voix
0

D' abord , vous devez déclarer l'objet de la fenêtre dans la portée actuelle.
Parce que tapuscrit aimerait connaître le type de l'objet.
Étant donné que l' objet de la fenêtre est défini quelque part ailleurs vous ne pouvez pas le redéfinir.
Mais vous pouvez le déclarer comme suit: -

declare var window: any;

Ce ne sera pas redéfinir l'objet de la fenêtre ou il ne crée pas une autre variable avec le nom window.
Cela signifie que la fenêtre est définie dans un autre et vous faites référence à juste portée actuelle.

Ensuite, vous pouvez vous référer à votre objet MyNamespace simplement par: -

window.MyNamespace

Et maintenant, le tapuscrit ne se plaindra pas.

Créé 01/06/2019 à 01:41
source utilisateur

voix
-1

Après avoir trouvé des réponses autour, je pense que cette page pourrait être utile. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Je ne sais pas sur l'histoire de la fusion de la déclaration, mais il explique pourquoi ce qui suit pourrait fonctionner.

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};
Créé 16/03/2017 à 17:38
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more