TypeScript泛型双向链表报错'T可实例化为无关类型'原因是什么?
报错成因
你遇到的TS报错核心是泛型作用域和类型匹配的问题:
- 你的
LinkedList<T>是泛型类,泛型参数T是类级别的,只有在实例化这个类的时候才会确定T的具体类型 - 你直接在类内部的
addTwo方法中硬编码传入了固定结构的对象,TS无法保证这个固定结构的对象和实例化时传入的T类型是兼容的:比如完全可以实例化一个LinkedList<number>类型的链表,此时addAtEnd要求传入number类型,你传入对象自然不符合类型要求,所以TS提前抛出了报错 - 你之前给
addAtEnd方法单独加<T>泛型的修改方式是错误的:方法级别的泛型T会覆盖类级别的泛型T,和Node<T>声明的类泛型不匹配,自然会触发和Node节点相关的类型错误
修复方案
分两种常见场景处理:
场景1:这个链表仅用来存储指定结构的评论数据
首先定义评论数据的接口:
interface IReview { id_user: number; id_touristic_place: number; review_title: string; review_desc: string; review_points: number; }
直接把链表类的泛型替换为该接口,或者给泛型添加约束:
// 方式1:直接固定存储类型 export class LinkedList implements ILinkedList<IReview> { // 其余代码不变,addTwo方法不需要修改就能正常运行 } // 方式2:给泛型加约束,保证T必须符合IReview结构 export class LinkedList<T extends IReview> implements ILinkedList<T> { // 其余代码不变 }
场景2:LinkedList是通用链表类,需要支持任意类型
不要把addTwo这种固定添加指定数据的方法写在通用类内部,把addTwo移到类外部使用:
// 先定义评论结构接口 interface IReview { id_user: number; id_touristic_place: number; review_title: string; review_desc: string; review_points: number; } // 实例化时指定链表存储的是IReview类型 const reviewLinkedList = new LinkedList<IReview>(); // 直接调用通用addAtEnd方法添加数据 reviewLinkedList.addAtEnd({ id_user: 1, id_touristic_place: 11, review_title: "Nice place", review_desc: "C:", review_points: 0, }); reviewLinkedList.addAtEnd({ id_user: 2, id_touristic_place: 11, review_title: "Good", review_desc: "Not bad at all ", review_points: 0, });
这种方式既保留了LinkedList的通用性,也能满足你存储评论数据的需求,同时符合TS的类型规范。
内容的提问来源于stack exchange,提问作者Juan Jose Garcia
相关产品推荐
相关产品推荐

