Como você definir explicitamente uma nova propriedade em `janela` na Máquina de escrever?

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

  •  13-12-2019
  •  | 
  •  

Pergunta

Eu configuração de espaços de nomes globais para meus objetos definindo explicitamente uma propriedade em window.

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

Transcrito sublinha MyNamespace e queixa-se de que:

A propriedade 'MyNamespace' não existe no valor do tipo 'janela' qualquer"

Eu posso fazer o código funcionar, declarando MyNamespace como uma variável de ambiente e soltando o window explicitação mas eu não quero fazer isso.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Como posso manter window lá e fazer o TypeScript feliz?

Como uma nota lateral acho que é especialmente engraçado que o TypeScript reclama, pois diz-me que window é do tipo any que por definitivamente pode conter qualquer coisa.

Foi útil?

Solução

Só encontrei a resposta para isso em outro StackOverflow pergunta a resposta.

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

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

Basicamente o que você precisa estender o existente window interface para dizer a ele sobre sua nova propriedade.

Outras dicas

Para mantê-lo dinâmico, basta usar:

(<any>window).MyNamespace

COMO O TYPESCRIPT ^3.4.3 ESTA SOLUÇÃO NÃO FUNCIONA MAIS

Ou...

você pode simplesmente digitar:

window['MyNamespace']

e você não vai obter um erro de compilação e funciona mesmo como escrever window.MyNamespace

Usando TSX?Nenhuma das outras respostas foram trabalhar para mim.

Aqui está o que eu fiz:

(window as any).MyNamespace

A resposta é aceite que eu costumava usar, mas com TypeScript 0.9.* ele não funciona mais.A nova definição do Window interface parece substituir completamente a definição interna, em vez de aumentar a ele.

Passei a fazer isso:

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

declare var window: MyWindow;

ATUALIZAÇÃO: Com TypeScript 0.9.5 aceitos resposta está funcionando novamente.

Global são "do mal" :), acho que a melhor maneira de ter, também, a portabilidade é:

Primeiro você exporta a interface:(por exemplo:./personalizado.janela.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Segundo importar

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

Terceiro elenco global var janela com CustomWindow

declare let window: CustomWindow;

Desta forma, você não tem também a linha vermelha em diferentes IDE se você usar com a existente atributos de objeto de janela, de modo que no final tentar:

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

Testado com Typescript 2.4.x e mais novo!

Se você precisa estender o window objeto com um tipo personalizado que não requer o uso de import você pode usar o seguinte método:

janela.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Consulte "Global de Aumento' na 'Declaração de Fusão' secção do Manual: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

Eu não preciso fazer isso, muitas vezes, o único caso que eu tive foi quando usando Redux Devtools com o middleware.

Eu simplesmente fiz:

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

Ou você poderia fazer:

let myWindow = window as any;

e, em seguida, myWindow.myProp = 'my value';

Para aqueles que utilizam o Angular CLI é simples:

src/livros.ts

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

meu-personalizado-utils.ts

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

Se você estiver usando o IntelliJ, você também necessário alterar a seguinte configuração no IDE, antes de seus novos livros, de pegar:

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

A maioria das outras respostas não são perfeitos.

  • Alguns deles simplesmente suprimir o tipo de inferência para a loja.
  • Algumas pessoas só se preocupa com a variável global como espaço de nomes, mas não como interface/classe

Eu também encontrar o problema semelhante, esta manhã.Eu tentei tantas "soluções" sobre ISSO, mas nenhum deles produzem nenhum tipo de erro absolutamente e permitem acionar tipo de salto no IDE(webstorm ou vscode).

Finalmente, a partir daqui

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

, Eu encontrar uma solução razoável para anexar tipagens para a variável global que atua como interface/classe e de espaço de nomes de ambos.

Exemplo a seguir:

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

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Agora, o código acima mescla as tipagens de espaço de nomes MyNamespace e interface MyNamespace para a variável global myNamespace(a propriedade da janela).

Depois de encontrar respostas, eu acho que esta página pode ser útil.https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Não tenho certeza sobre o histórico de declaração de fusão, mas explica por que o seguinte pode trabalhar.

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

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

Aqui está como fazê-lo, se você estiver usando Transcrito De Definição De Gestor De!

npm install typings --global

Criar typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Instalação personalizada digitando:

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

Feito, usá-lo! O Typescript não reclamar mais:

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

Se você estiver usando o Typescript 3.x, você pode ser capaz de omitir o declare global parte em outras respostas e, em vez disso, basta usar:

interface Window {
  someValue: string
  another: boolean
}

Isso funcionou comigo quando utilizar o Typescript 3.3, WebPack e TSLint.

Typscript não executa tipo verificação nas propriedades de seqüência de caracteres.

window["newProperty"] = customObj;

Idealmente, a variável global cenário deve ser evitado.Eu uso às vezes para depurar um objeto no console do navegador.

De referência (esta é a resposta correta):

Dentro de um .d.ts arquivo de definição de

type MyGlobalFunctionType = (name: string) => void

Se você trabalha no navegador, você pode adicionar membros a janela do navegador contexto de reabertura da Janela de interface:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

A mesma idéia para NodeJS:

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

Agora você declarar a variável root (que vai realmente viver na janela ou global)

declare const myGlobalFunction: MyGlobalFunctionType;

Em seguida, em regular .ts arquivo, mas importados como efeito colateral, você realmente implementá-lo:

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

E, finalmente usá-lo em outro lugar no codebase, com:

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

myGlobalFunction("Kevin");

Fazer uma interface personalizada estende-se a Janela e adicionar propriedades personalizadas como opcional.

Então, vamos a customWindow que usam a interface personalizada, mas valorizado com a janela original.

Ele trabalhou com o typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 

Para aqueles que querem montar um computadas ou propriedade dinâmica no window objeto, você verá que não é possível com os declare global o método.Para esclarecer para este caso de uso

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

Você pode tentar fazer algo parecido com isso

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

Acima de erro embora.Isso porque, no Typescript, interfaces de não jogar bem com propriedades calculadas e vai lançar um erro como

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

Para contornar esse problema, você pode ir com a sugerir de fundição window para <any> assim, você pode fazer

(window as any)[DynamicObject.key]

Eu queria usar isso em um Angulares (6) biblioteca hoje e ele me levou um tempo para chegar a este funcionar como esperado.

Para a minha biblioteca, para uso de declarações que eu tinha que usar o d.ts extensão para o arquivo, que declara que as novas propriedades do objeto global.

Então, no final, o arquivo terminou com algo como:

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

Uma vez criada, não se esqueça de expô-lo no seu public_api.ts.

Que ele fez por mim.Espero que isso ajude.

Primeiro você precisa declarar o objeto de janela no escopo atual.
Porque transcrito gostaria de saber o tipo do objeto.
Desde que o objeto da janela é definido em outro lugar você não pode redefini-la.
Mas você pode declará-lo como segue:-

declare var window: any;

Isso não vai redefinir o objeto de janela ou não vai criar outra variável com o nome window.
Isso significa que a janela é definida em outro lugar, e você está apenas a referência a ele no escopo atual.

Em seguida, você pode consultar o seu MyNamespace objeto simplesmente:-

window.MyNamespace

Ou você pode definir uma nova propriedade em window objeto simplesmente:-

window.MyNamespace = MyObject

E agora o typescript não vai reclamar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top