如何避免Cypress POM页面对象中重复的JSDoc类型声明?
解决Cypress POM架构中重复JSDoc类型声明的问题
核心思路
通过定义JSDoc工具类型批量转换字符串选择器的类型,替代逐个属性添加@type的重复操作,同时保留IDE智能提示能力。
实现步骤
1. 定义映射工具类型
先声明一个通用映射类型,自动将对象中的字符串属性转换为Cypress.Chainable<JQuery<HTMLElement>>,非字符串属性保持原类型:
/** * @template T * @typedef {{ [K in keyof T]: T[K] extends string ? Cypress.Chainable<JQuery<HTMLElement>> : T[K] }} ProxiedPageObject */
2. 更新代理函数的类型注释
修改getPageObjectProxy的JSDoc,明确它接收原始页面对象(含字符串选择器),返回经过类型转换的代理对象:
/** * @template T * @param {T} pageObject 原始页面对象(包含字符串选择器和方法) * @returns {ProxiedPageObject<T>} 代理后的页面对象(字符串选择器转为Cypress元素链) */ export const getPageObjectProxy = pageObject => new Proxy(pageObject, { get(target, prop) { if (typeof target[prop] === 'string') { return cy.get(target[prop]); } return target[prop]; } });
3. 简化页面对象定义
现在无需给每个字符串属性单独加@type,直接定义原始对象即可,IDE会自动推导代理后的属性类型:
export const homePage = getPageObjectProxy({ searchField: 'input', logOutButton: '[data-testid=logout-button]', modeDropdown: '[data-testid=mode-dropdown]', setMode(name) { this.modeDropdown.click(); this.modeDropdown.children().contains(name).click(); } });
原理说明
- 工具类型
ProxiedPageObject<T>通过映射类型遍历原始对象的所有属性:若属性为字符串类型,则替换为Cypress元素链类型;否则保留原类型。 - 代理函数的返回值指定为
ProxiedPageObject<T>后,IDE会根据传入的原始对象自动推导代理后的属性类型,实现正常的智能提示。
内容的提问来源于stack exchange,提问作者oleksiisedun
相关产品推荐
相关产品推荐

