我经历了TS handbook,并提出了类型别名的概念,我认为它非常有吸引力。然后,我尝试运行此代码段:
type LinkedList<T> = T & { next: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
给出的内容(TS v2.9.1):error TS2454: Variable 'people' is used before being assigned.
因此,我已按照以下步骤初始化people
:
var people: LinkedList<Person> =
{name: "John", next: {name: "Jannet", next: {name: "Joanna", next: {name: "Adam", next: undefined}}}};
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
但是现在我得到了TSError:
error TS2322: Type '{ name: string; next: { name: string; next: { name: string; next: { name: string; next: undefined...' is not assignable to type 'LinkedList<Person>'
。
我在哪里弄错了?
答案 0 :(得分:2)
@TitianCernicovaDragomir的答案是正确的;通常,您需要某种基本情况,以便您的链表可以具有有限的长度。但是,在极少数情况下,您想要做一个符合原始LinkedList<Person>
定义的类型安全的事情,可以执行以下操作:
class Ouroboros {
name = "AlphaAndOmega";
next = this; //
}
const people: LinkedList<Person> = new Ouroboros();
console.log(people.name); // "AlphaAndOmega"
console.log(people.next.name); // "AlphaAndOmega"
console.log(people.next.next.name); // "AlphaAndOmega"
console.log(people.next.next.next.name); // "AlphaAndOmega"
在这种情况下,people
是一个circular linked list,只有一个唯一的Person
元素。
答案 1 :(得分:1)
如果您正在使用字符串空检查(通过strict
或strictNullChecks
选项),则undefined
无法分配给LinkedList<T>
。
最简单的选择是使next
字段为可选
type LinkedList<T> = T & { next?: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person> =
{ name: "John", next: { name: "Jannet", next: { name: "Joanna", next: { name: "Adam", next: undefined } } } };
var s = people.name;
var s = people.next!.name;
var s = people.next!.next!.name;
var s = people.next!.next!.next!.name;
问题是现在下一个字段是可选的,因此我们必须在每次访问时检查它是否不为空,或者像我上面所做的那样,使用不为空的断言运算符(!
)
修改
如果希望将people
精确键入对象文字的结构,但要检查对象文字是否符合LinkedList<Person>
,则可以使用额外的函数来创建将推断类型的对象对象文字的大小,但如果不符合LinkedList<Person>
,则会引发错误。好处是我们不需要任何非null的断言(!
),在这种情况下,最大的缺点是列表的长度是固定的,因此不是很有用,但是有趣的是:)>
function createLinkedList<T extends LinkedList<Person>>(p: T) {
return p;
}
var people = createLinkedList({ name: "John", next: { name: "Jannet", next: { name: "Joanna", next: { name: "Adam" } } } });
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;