Comment définir explicitement une nouvelle propriété sur "fenêtre" dans le Tapuscrit?

StackOverflow https://stackoverflow.com//questions/12709074

  •  13-12-2019
  •  | 
  •  

Question

J'configuration de l'espace de noms global pour mes objets par la définition explicite d'un bien sur window.

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

Tapuscrit souligne MyNamespace et se plaint que:

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

Je peux faire le code de travail en déclarant MyNamespace comme ambiante variable et l'abandon de l' window explicite mais je ne veux pas le faire.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Comment puis-je garder window là-bas et faire Tapuscrit heureux?

Comme une note de côté je trouve ça particulièrement drôle que la Machine se plaint car il me dit que window est de type any qui en doute peut contenir quoi que ce soit.

Était-ce utile?

La solution

Viens de trouver la réponse à cette un autre StackOverflow question réponse.

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

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

Fondamentalement, vous avez besoin de prolonger l'existant window interface pour le dire au sujet de votre nouvelle propriété.

Autres conseils

Pour garder la dynamique, il suffit d'utiliser:

(<any>window).MyNamespace

COMME DE TAPUSCRIT ^3.4.3 CETTE SOLUTION NE FONCTIONNE PLUS

Ou...

vous pouvez simplement taper:

window['MyNamespace']

et vous ne obtenez une erreur de compilation, et il fonctionne de la même façon que la saisie d' window.MyNamespace

À l'aide de la TSX?Aucune des autres réponses ont été de travailler pour moi.

Voici ce que j'ai fait:

(window as any).MyNamespace

La accepté de répondre est ce que j'ai l'habitude d'utiliser, mais avec Tapuscrit de 0,9.* il ne fonctionne plus.La nouvelle définition de l' Window l'interface semble remplacer complètement intégré dans la définition, à la place de l'augmentant.

J'ai commencé à le faire à la place:

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

declare var window: MyWindow;

Mise à JOUR: Avec Tapuscrit 0.9.5 accepté la réponse est de travailler à nouveau.

Mondiale sont "mal" :), je pense que le meilleur moyen d'avoir également la portabilité est:

D'abord de l'exportation de l'interface:(par exemple:./la coutume.de la fenêtre.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Deuxième vous importez

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

Troisième cast global var fenêtre avec CustomWindow

declare let window: CustomWindow;

De cette façon, vous n'avez pas également la ligne rouge dans les différents IDE si vous utilisez existant avec les attributs de l'objet window, donc, à la fin, essayez:

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

Testé avec Tapuscrit 2.4.x et récent!

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

de la fenêtre.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

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

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

Je l'ai fait simplement:

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

Ou vous pourriez faire:

let myWindow = window as any;

et puis myWindow.myProp = 'my value';

Pour ceux qui utilisent le Angulaire de la CLI c'est simple:

src/polyfills.ts

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

mon-custom-utils.ts

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

Si vous êtes à l'aide de l'Ide, il fallait aussi changer le paramètre suivant dans l'IDE avant que votre nouveau polyfills de ramassage:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.

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

  • Certains d'entre eux vient de supprimer l'inférence de type pour la boutique.
  • Certains autres se soucie uniquement de variable globale en tant qu'espace de noms, mais pas que/l'interface de la classe

Je rencontre également le même problème ce matin.J'ai essayé beaucoup de "solutions", mais aucun d'entre eux ne produisent aucune erreur de type absolument et permettant le déclenchement de type saut en IDE(webstorm ou vscode).

Enfin, à partir d'ici

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

, J'ai trouver une solution raisonnable joindre typings pour une variable globale qui agit comme interface/classe et de l'espace de noms à la fois.

Exemple ci-dessous:

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

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Maintenant, le code ci-dessus fusionne les typings de l'espace de noms MyNamespace et l'interface MyNamespace dans la variable globale myNamespace(la propriété de la fenêtre).

Après trouver des réponses autour, je pense que cette page pourrait être utile.https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Pas sûr au sujet de l'histoire de la déclaration de la fusion, mais elle explique pourquoi les suivantes pourraient travailler.

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

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

Voici comment le faire, si vous êtes en utilisant Tapuscrit Définition Manager!

npm install typings --global

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

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Installer personnalisés en tapant:

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

Fait, l'utiliser! La machine ne se plaignent plus:

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

Si vous utilisez la Machine 3.x, vous pouvez être en mesure d'omettre le declare global partie dans les autres réponses et, au lieu de simplement utiliser:

interface Window {
  someValue: string
  another: boolean
}

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

Typscript ne pas effectuer typecheck sur les propriétés de la chaîne.

window["newProperty"] = customObj;

Idéalement, la variable globale scénario doit être évitée.Je l'utilise parfois pour déboguer un objet dans le navigateur de la console.

Pour la référence (c'est la bonne réponse):

À l'intérieur d'un .d.ts fichier de définition de

type MyGlobalFunctionType = (name: string) => void

Si vous travaillez dans le navigateur, vous ajoutez des membres à la fenêtre du navigateur contexte par la réouverture de la Fenêtre de l'interface:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Même idée pour NodeJS:

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

Maintenant, vous déclarez la racine de la variable (qui vivent sur la fenêtre ou global)

declare const myGlobalFunction: MyGlobalFunctionType;

Puis dans un .ts fichier, mais importées comme effet secondaire, vous avez réellement la mettre en œuvre:

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

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

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

myGlobalFunction("Kevin");

Faire une interface personnalisée s'étend de la Fenêtre et ajouter votre propriété personnalisée à titre d'option.

Ensuite, laissez le customWindow que l'utilisation de l'interface personnalisée, mais apprécié, avec la fenêtre d'origine.

Il a travaillé avec l'typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 

Pour ceux qui veulent créer une angiographie ou une propriété dynamique sur le window objet, vous trouverez cela n'est pas possible avec la declare global la mé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 tenter de faire quelque chose comme ceci

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

Ci-dessus l'erreur si.C'est parce que en caractères d'imprimerie, les interfaces ne sont pas bien jouer avec les propriétés calculées et lèvera une erreur de ce type

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èrent de casting window pour <any> de sorte que vous pouvez faire

(window as any)[DynamicObject.key]

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

Pour ma bibliothèque à utiliser déclarations, j'ai dû utiliser l' d.ts l'extension du fichier qui déclare les nouvelles propriétés de l'objet global.

Donc en fin de compte, le fichier à la fin quelque chose comme:

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

Une fois créé, n'oubliez pas de les exposer dans votre public_api.ts.

Qu'il a fait pour moi.Espérons que cette aide.

Vous devez d'abord déclarer la fenêtre de l'objet dans le champ d'application actuel.
Parce que tapuscrit voudrais savoir le type de l'objet.
Depuis la fenêtre de l'objet est défini quelque part d'autre, vous ne pouvez pas redéfinir.
Mais vous pouvez la déclarer comme suit:-

declare var window: any;

Ce ne sera pas redéfinir l'objet de la fenêtre ou il ne va pas créer une autre variable nom window.
Cela signifie que la fenêtre est défini quelque part d'autre et vous êtes simplement en le référençant dans le champ d'application actuel.

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

window.MyNamespace

Ou vous pouvez définir la propriété dans window objet simplement:-

window.MyNamespace = MyObject

Et maintenant, le tapuscrit de ne pas se plaindre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top