TypeScript类型别名疑问:如何实现自引用的LinkedList可运行类型?
嘿,我来帮你搞定这两个疑问~
关于示例代码的可运行性与复杂度
你看到的官方示例代码只是展示了类型定义的写法,没给具体的变量赋值,所以直接跑会报错,但实际可运行的版本一点都不复杂,只需要给people变量创建符合类型的实例就行。比如:
type LinkedList<T> = T & { next: LinkedList<T> | null }; // 加个|null让链表能终止 interface Person { name: string; } // 创建一个可运行的链表实例 const people: LinkedList<Person> = { name: "Alice", next: { name: "Bob", next: { name: "Charlie", next: null } } }; // 现在这些访问就完全没问题了 const s1 = people.name; // "Alice" const s2 = people.next?.name; // "Bob" const s3 = people.next?.next?.name; // "Charlie"
你看,核心的类型定义和官方示例几乎一样,只是加了| null让链表有终止条件,然后简单构建一个嵌套对象就能运行了,复杂度完全可控。
自引用类型的正确写法
你写的type LinkedList<T> = T & { next: LinkedList<T> };其实已经是正确的自引用类型定义了,但有个小问题:如果严格按照这个类型,链表永远没法结束(因为next必须是LinkedList<T>,不能为null),实际开发中我们通常会给next加上null的可选终止类型,也就是LinkedList<T> | null,这样才能构建出有尽头的链表。
另外,TypeScript从2.1版本开始就完美支持这种自引用的类型别名了,不管是交叉类型(&)还是对象类型里的自引用,都能正常识别。比如你也可以用接口来写自引用:
interface LinkedList<T> extends T { next: LinkedList<T> | null; }
效果和类型别名是一样的,看你个人习惯选择就行。
内容的提问来源于stack exchange,提问作者Fumio Nonaka
相关产品推荐
相关产品推荐

