我通过显式设置窗口上的属性为我的对象设置全局名称空间。

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

TypeScript强调MyNamespace,并抱怨:

属性“MyNamespace”在类型为“window”的值上不存在 任何“

我可以通过将MyNamespace声明为环境变量并删除窗口显式来使代码工作,但我不想这样做。

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

我如何保持窗口在那里,让TypeScript满意?

作为旁注,我发现特别有趣的是,TypeScript抱怨,因为它告诉我,窗口的类型是any,它肯定可以包含任何东西。


当前回答

创建一个扩展Window的自定义界面,并将自定义属性添加为可选属性。

然后,让customWindow使用自定义接口,但值与原始窗口相同。

它与TypeScript 3.1.3一起工作。

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {}

其他回答

如果您需要使用需要使用import的自定义类型来扩展窗口对象,您可以使用以下方法:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

请参阅手册的“声明合并”部分中的全局增强。

我不需要经常这样做。我唯一遇到的情况是在中间件中使用Redux DevTools。

我只是做了:

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

或者你可以这样做:

let myWindow = window as any;

然后是myWindow。myProp = '我的值';

使用create-react-app v3.3,我发现实现这一点最简单的方法是扩展自动生成的react-app-env.d.ts中的Window类型:

interface Window {
    MyNamespace: any;
}

完整和简短的回答

1-在tsconfig.json中添加typeRoots属性:

{
  "compilerOptions": {
    ...
    "typeRoots": ["src/@types", "node_modules/@types"]
    ...
  }
}

2-扩展窗口类型

// file: src/@types/global.d.ts

declare global {
    interface Window { customProperty: <type>; }
}

我刚刚在另一个Stack Overflow问题的答案中找到了这个问题的答案。

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

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

基本上,您需要扩展现有的窗口界面来告诉它您的新属性。