TypeScript报错TS2339、TS2345:object类型属性不存在及参数类型不兼容
TypeScript 访问object类型属性报错修复
报错根因
draw方法入参data被定义为object[]类型,TS中内置的object类型仅标记值为非原始类型的引用值,不包含任何自定义属性定义,直接访问item.name、item.id自然会触发TS2339属性不存在的错误。- 单独给
forEach回调的item加类型标注无法解决问题:TS会校验回调参数类型与数组元素类型的兼容性,数组元素被定义为无属性的object类型,无法兼容带name、id属性的结构,因此触发TS2345类型不匹配错误。
修复方式
优先从入参层面修正类型定义,不要用宽泛的object类型,给数据定义明确的结构:
- 先定义列表项的类型结构
- 将
draw方法的data入参类型从object[]替换为定义好的明确类型,遍历的时候TS会自动推导item类型,不需要额外标注。
修正后的完整代码:
// 定义数据源项结构 interface SourceItem { name: string; id: string; } class Sources { // 修正入参类型,从源头统一类型约束 draw(data: SourceItem[]): void { const fragment = document.createDocumentFragment(); const sourceItemTemp = document.querySelector("#sourceItemTemp") as HTMLTemplateElement; data.forEach((item) => { // 额外修正:模板克隆节点不是HTMLInputElement,之前的类型断言错误,这里修正为正确的节点类型 const sourceClone = sourceItemTemp.content.cloneNode(true) as HTMLElement; const sourceItemName = sourceClone.querySelector(".source__item-name"); const sourceItem = sourceClone.querySelector(".source__item"); if (sourceItemName && sourceItem) { sourceItemName.textContent = item.name; sourceItem.setAttribute("data-source-id", item.id); } fragment.append(sourceClone); }); const doc = document.querySelector(".sources"); if (doc) { doc.append(fragment); } } }
如果暂时无法修改draw方法的入参类型,可以在遍历内部做类型断言临时绕过(不推荐长期使用,类型约束缺失会提升后续维护成本):
data.forEach((item) => { const { name, id } = item as { name: string; id: string }; // 后续直接使用name、id变量即可 })
内容的提问来源于stack exchange,提问作者Maksim Lapko
相关产品推荐
相关产品推荐

