如何用JSDoc扩展Window/globalThis对象?添加theme属性报错求助
解决JSDoc扩展Window对象属性的类型报错问题
问题场景
尝试用JSDoc给全局window对象添加自定义theme属性,定义Routes和ThemeObject类型后,用两种@typedef方式扩展Window和globalThis,但VS Code持续提示错误:
Property 'theme' does not exist on type 'Window & typeof globalThis'
原代码:
/** * @typedef {Object} Routes * @property {string} root - Root URL * @property {string} product - Product URL */ /** * @typedef {Object} ThemeObject * @property {Routes} routes - All Shopify routes */ /** * The global `theme` object. * @typedef {Window & { theme: ThemeObject }} */ /** * The global `Window` object. * @typedef {globalThis & { theme: ThemeObject }} Window */ window.emitter = new Emitter(); window.theme.routes.root;
解决方案
问题源于@typedef写法未被VS Code的TypeScript服务正确识别,以下三种方式可解决:
方式一:用@augments扩展Window接口
声明继承自原生Window的接口,添加自定义属性以扩展全局类型:
/** * @typedef {Object} Routes * @property {string} root - Root URL * @property {string} product - Product URL */ /** * @typedef {Object} ThemeObject * @property {Routes} routes - All Shopify routes */ /** * @augments Window * @property {ThemeObject} theme - 自定义全局theme对象 */ function Window() {} // 直接赋值使用 window.theme = { routes: { root: '/', product: '/products' } }; window.theme.routes.root; // 无类型报错
方式二:给window.theme做类型断言
仅需当前文件获得类型提示时,直接用@type断言标记:
/** * @typedef {Object} Routes * @property {string} root - Root URL * @property {string} product - Product URL */ /** * @typedef {Object} ThemeObject * @property {Routes} routes - All Shopify routes */ // 类型断言标记window.theme window.theme = /** @type {ThemeObject} */ ({ routes: { root: '/', product: '/products' } }); window.theme.routes.root; // 无类型报错
方式三:全局重定义Window类型
通过@global标记确保类型全局生效,需启用JS类型检查(在settings.json中设置"javascript.implicitProjectConfig.checkJs": true):
/** * @typedef {Object} Routes * @property {string} root - Root URL * @property {string} product - Product URL */ /** * @typedef {Object} ThemeObject * @property {Routes} routes - All Shopify routes */ /** * @global * @typedef {Window & { theme: ThemeObject }} Window */ window.theme.routes.root; // 类型识别正常
内容的提问来源于stack exchange,提问作者Tobias Madsen
相关产品推荐
相关产品推荐

