TypeScript에서 `window`에 새 속성을 어떻게 명시적으로 설정합니까?

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

  •  13-12-2019
  •  | 
  •  

문제

명시적으로 속성을 설정하여 개체에 대한 전역 네임스페이스를 설정했습니다. window.

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

TypeScript 밑줄 MyNamespace 그리고 이렇게 불평합니다.

'mynamespace'속성은 '창'유형의 가치에 존재하지 않습니다.

다음을 선언하여 코드를 작동시킬 수 있습니다. MyNamespace 주변 변수로 사용하고 window 명확하지만 나는 그렇게 하고 싶지 않습니다.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

어떻게 지킬 수 있나요? window 거기에 들어가서 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

허용되는 답변은 제가 사용했던 답변이지만 TypeScript 0.9.*에서는 더 이상 작동하지 않습니다.의 새로운 정의 Window 인터페이스는 내장된 정의를 확장하는 대신 완전히 대체하는 것 같습니다.

나는 대신 이렇게 했습니다:

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

declare var window: MyWindow;

업데이트: TypeScript 0.9.5에서는 허용되는 답변이 다시 작동합니다.

글로벌은 "악"입니다. :) 이식성을 갖는 가장 좋은 방법은 다음과 같습니다.

먼저 인터페이스를 내보냅니다.(예:./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

두 번째로 가져옵니다.

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

CustomWindow를 사용한 세 번째 캐스트 전역 변수 창

declare let window: CustomWindow;

이런 식으로 창 개체의 기존 속성과 함께 사용하는 경우 다른 IDE에도 빨간색 선이 없으므로 마지막에 다음을 시도하십시오.

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

Typescript 2.4.x 및 최신 버전으로 테스트되었습니다!

연장이 필요한 경우 window 다음을 사용해야 하는 사용자 정의 유형이 있는 객체 import 다음 방법을 사용할 수 있습니다.

window.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';

이용하시는 분들을 위해 각도 CLI 그것은 간단하다:

src/polyfills.ts

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

내-사용자 정의-utils.ts

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

IntelliJ를 사용하는 경우 새 폴리필을 선택하기 전에 IDE에서 다음 설정도 변경해야 합니다.

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

다른 답변의 대부분은 완벽하지 않습니다.

  • 그 중 일부는 상점에 대한 유형 추론을 억제합니다.
  • 다른 것 중 일부는 전역 변수를 네임스페이스로만 고려하고 인터페이스/클래스로는 고려하지 않습니다.

오늘 아침에도 비슷한 문제가 발생했습니다.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 {
    // ...
}

이제 위의 코드는 네임스페이스의 입력을 병합합니다. 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 || {};

Typescript 3.x를 사용하는 경우 다음을 생략할 수 있습니다. declare global 다른 답변에 참여하고 대신 다음을 사용하십시오.

interface Window {
  someValue: string
  another: boolean
}

Typescript 3.3, WebPack 및 TSLint를 사용할 때 이것은 나와 함께 작동했습니다.

Typscript는 문자열 속성에 대한 유형 검사를 수행하지 않습니다.

window["newProperty"] = customObj;

이상적으로는 전역 변수 시나리오를 피해야 합니다.나는 가끔 브라우저 콘솔에서 개체를 디버깅하는 데 사용합니다.

참고로 (정답입니다):

내부 .d.ts 정의 파일

type MyGlobalFunctionType = (name: string) => void

브라우저에서 작업하는 경우 Window의 인터페이스를 다시 열어 브라우저의 창 컨텍스트에 멤버를 추가합니다.

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.

그것은 나를 위해 해냈습니다.도움이 되었기를 바랍니다.

먼저 현재 범위에서 창 개체를 선언해야 합니다.
TypeScript는 객체의 유형을 알고 싶어하기 때문입니다.
창 개체는 다른 곳에 정의되어 있으므로 다시 정의할 수 없습니다.
하지만 다음과 같이 선언할 수 있습니다.

declare var window: any;

이것은 창 개체를 재정의하지 않거나 이름이 있는 다른 변수를 생성하지 않습니다. window.
이는 창이 다른 곳에 정의되어 있고 현재 범위에서 이를 참조하고 있음을 의미합니다.

그런 다음 다음과 같이 간단히 MyNamespace 개체를 참조할 수 있습니다.

window.MyNamespace

또는 새 속성을 설정할 수 있습니다. window 간단히 말해서 :-

window.MyNamespace = MyObject

이제 타이프스크립트는 불평하지 않을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top