¿Cómo se establece explícitamente una nueva propiedad en `window` a máquina de escribir?

votos
247

I fijó espacios de nombres globales para mis objetos de establecer explícitamente una propiedad en window.

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

Mecanografiado subraya MyNamespacey se queja de que:

La propiedad 'MyNamespace' no existe en el valor de la 'ventana' cualquier tipo

Puedo hacer el trabajo de código por el que se declara MyNamespacecomo una variable ambiental y soltando el windowcarácter explícito, pero no quiero hacer eso.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

¿Cómo puedo mantener windowallí y hacer mecanografiado feliz?

Como nota al margen Me resulta especialmente curioso que mecanografiado se queja ya que me dice que windowes del tipo anyque, por definitivamente puede contener cualquier cosa.

Publicado el 03/10/2012 a las 14:01
fuente por usuario
En otros idiomas...                            


19 respuestas

votos
253

Para mantenerlo dinámico, sólo tiene que utilizar:

(<any>window).MyNamespace
Respondida el 09/06/2015 a las 19:18
fuente por usuario

votos
235

Acaba de encontrar la respuesta a esto en la respuesta de otra pregunta StackOverflow .

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

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

Básicamente necesita extender el vigente windowinterfaz de contarla acerca de su nueva propiedad.

Respondida el 03/10/2012 a las 14:46
fuente por usuario

votos
127

O...

sólo se puede escribir:

window['MyNamespace']

y usted no conseguirá un error de compilación y funciona lo mismo que introducir window.MyNamespace

Respondida el 20/11/2012 a las 20:36
fuente por usuario

votos
84

Por TSX? Ninguna de las otras respuestas estaban trabajando para mí.

Esto es lo que hice:

(window as any).MyNamespace
Respondida el 15/08/2016 a las 20:25
fuente por usuario

votos
46

La respuesta aceptada es lo que solía usar, pero con mecanografiado 0.9. * Ya no funciona. La nueva definición de la Windowinterfaz parece sustituir por completo la definición incorporado, en lugar de aumentarlo.

He llevado a hacer esto en su lugar:

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

declare var window: MyWindow;

ACTUALIZACIÓN: Con mecanografiado 0.9.5 la respuesta aceptada está funcionando de nuevo.

Respondida el 27/08/2013 a las 22:22
fuente por usuario

votos
29

Si necesita ampliar el windowobjeto con un tipo personalizado que requiere el uso de importque se puede utilizar el siguiente método:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Ver 'Global Aumento' en la sección 'Declaración de la concentración del Manual: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

Respondida el 23/10/2016 a las 12:24
fuente por usuario

votos
19

Global están "mal" :), creo que la mejor manera de tener también la portabilidad es:

En primer lugar se exporta la interfaz: (por ejemplo: ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

En segundo lugar se importa

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

En tercer lugar mundial fundido ventana var con CustomWindow

declare let window: CustomWindow;

De esta manera usted no tiene la línea roja también en diferentes IDE si se utiliza con los atributos existentes del objeto de la ventana, por lo que en el intento final:

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

Probado con 2.4.x de imprenta

Respondida el 27/07/2017 a las 10:28
fuente por usuario

votos
8

He aquí cómo hacerlo, si estás usando mecanografiado Gestor Definición !

npm install typings --global

crear typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Instalar su escritura personalizado:

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

Hecho, usarlo ! Letra de imprenta no se quejará más:

window.MyNamespace = window.MyNamespace || {};
Respondida el 19/11/2016 a las 18:31
fuente por usuario

votos
7

No necesito hacer esto muy a menudo, el único caso que he tenido fue cuando se utiliza Redux Devtools con el middleware.

Yo simplemente hice:

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

O usted podría hacer:

let myWindow = window as any;

y entonces myWindow.myProp = 'my value';

Respondida el 06/06/2018 a las 13:13
fuente por usuario

votos
5

La mayoría de las otras respuestas no son perfectos.

  • Algunos de ellos sólo suprimen la inferencia de tipos para la tienda.
  • Algunos de los otros sólo se preocupa por la variable global como espacio de nombres, pero no como interfaz / clase

También me encuentro con el problema similar esta mañana. He intentado tantas "soluciones" en la SO, pero ninguno de ellos no producen ningún tipo de error absoluto y permitir la activación de tipo de salto en IDE (WebStorm o vscode).

Por último, desde aquí

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

, Me parece una solución razonable para adjuntar tipificaciones para la variable global que actúa como interfaz / clase y espacio de nombres tanto .

Ejemplo es el siguiente:

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

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Ahora, el código anterior fusiona las tipificaciones de espacio de nombres MyNamespacey la interfaz MyNamespaceen la variable global myNamespace(la propiedad de la ventana).

Respondida el 19/05/2017 a las 00:26
fuente por usuario

votos
5

Si estás usando el angular CLI es muy sencillo (probado en rc.0 CLI):

src / polyfills.ts

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

my-custom-utils.ts

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

Estoy usando IntelliJ, por lo que también es necesario cambiar la siguiente configuración en el IDE antes de que mis nuevos polyfills recogidos:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
Respondida el 21/03/2017 a las 10:38
fuente por usuario

votos
2

Para aquellos que quieren establecer una propiedad computada o dinámica en el windowobjeto, usted encontrará que no es posible con el declare globalmétodo. Para aclarar para este caso de uso

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

Se podría intentar hacer algo como esto

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

Lo anterior será error sin embargo. Esto se debe a máquina de escribir, las interfaces no juegan bien con propiedades calculadas y tirarán un error como

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

Para evitar esto, se puede ir con la fundición de sugerir windowque <any>lo que puede hacer

(window as any)[DynamicObject.key]
Respondida el 13/02/2019 a las 00:15
fuente por usuario

votos
2

Hacer una interfaz personalizada se extiende la ventana y añadir su propiedad personalizada como opcionales.

A continuación, dejar que el customWindow que utilizan la interfaz personalizada, pero valorada con la ventana original.

Se trabajó con la typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
Respondida el 12/11/2018 a las 07:29
fuente por usuario

votos
2

Quería utilizar esto en un (6) biblioteca angular hoy y me tomó un tiempo para conseguir que esto funcione como se espera.

Con el fin de mi biblioteca para usar las declaraciones que tuve que usar la d.tsextensión para el archivo que declara las nuevas propiedades del objeto global.

Así que al final, el archivo terminó con algo como:

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

Una vez creado, no se olvide de exponerlo en su public_api.ts.

Con eso fue suficiente para mí. Espero que esto ayude.

Respondida el 01/08/2018 a las 11:29
fuente por usuario

votos
2

A modo de referencia (esta es la respuesta correcta):

Dentro de un .d.tsarchivo de definición

type MyGlobalFunctionType = (name: string) => void

Si trabaja en el navegador, se agrega a los miembros contextual de la ventana del navegador mediante la reapertura de la interfaz de ventana:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

La misma idea de NodeJS:

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

Ahora se declara la variable raíz (que realmente vivirán en la ventana o global)

declare const myGlobalFunction: MyGlobalFunctionType;

Luego, en un habitual .tsde archivos, pero importan como efecto secundario, en realidad se implementan:

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

Y finalmente utilizarlo en otras partes del código base, ya sea con:

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

myGlobalFunction("Kevin");
Respondida el 20/04/2017 a las 12:50
fuente por usuario

votos
1

Si está utilizando 3.x Letra de imprenta, es posible que pueda omitir la declare globalparte de las otras respuestas y en su lugar sólo tiene que utilizar:

interface Window {
  someValue: string
  another: boolean
}

Este trabajó conmigo cuando se utiliza imprenta 3.3, WebPack y TSLint.

Respondida el 12/02/2019 a las 21:50
fuente por usuario

votos
0

Typescript no realiza typecheck en propiedades de cadena.

window["newProperty"] = customObj;

Idealmente, el escenario variable global debe evitarse. Lo utilizo a veces para eliminar errores de un objeto en la consola del navegador.

Respondida el 18/06/2019 a las 22:01
fuente por usuario

votos
0

Primero tendrá que declarar el objeto de la ventana en su alcance actual.
Debido a máquina le gustaría saber el tipo de objeto.
Desde objeto de la ventana se define en otro lugar que no se puede redefinirlo.
Pero se puede declarar como sigue: -

declare var window: any;

Esto no va a redefinir el objeto de la ventana o que no va a crear otra variable con el nombre window.
Esto significa que la ventana se define en otro lugar y sólo se hace referencia a que en el ámbito actual.

A continuación, se puede hacer referencia a su objeto MyNamespace simplemente: -

window.MyNamespace

Y ahora el manuscrito no se quejará.

Respondida el 01/06/2019 a las 01:41
fuente por usuario

votos
-1

Después de encontrar respuestas alrededor, creo que esta página puede ser útil. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation No está seguro acerca de la historia de la fusión declaración, pero explica por qué el siguiente podría funcionar.

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

window.MyNamespace = window.MyNamespace || {};
Respondida el 16/03/2017 a las 14:38
fuente por usuario

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