Fumio Nonaka
Fumio Nonaka

Reputation: 61

Example code of "Type Aliases" to work

The example code below is from the Handbook of TypeScript official site. It just describes how its style is something like and does not work. Is actual code to work so complicated? I have no idea how to type a property as the same type as itself (type LinkedList = T & { next: LinkedList }).

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;

Upvotes: 0

Views: 39

Answers (2)

jcalz
jcalz

Reputation: 330366

It is possible to implement a type like this with strict null checking (responding to @artem). You don't have to make it actually infinite, only potentially infinite... such as circular. For example:

type LinkedList<T> = T & { next: LinkedList<T> };

interface Person {
  name: string;
}

// new LLP("name") produces a circular LinkedList<Person>
class LLP implements LinkedList<Person> {
  public next: LinkedList<Person>;
  constructor(public name: string, next?: LinkedList<Person>) {
    this.next = next ? next : this;
  }
}

var people: LinkedList<Person> = new LLP("Alice", new LLP("Bob", new LLP("Carol"));
console.log(people.name); // Alice
console.log(people.next.name); // Bob
console.log(people.next.next.name); // Carol
console.log(people.next.next.next.name); // Also Carol
console.log(people.next.next.next.next.name); // Forever Carol

I agree it's a weird type; usually you'd give a way to bail out by having next be optional, as @artem indicates.

Upvotes: 2

artem
artem

Reputation: 51789

I have no idea how to type a property as the same type as itself (type LinkedList = T & { next: LinkedList }).

type LinkedList<T> = T & { next: LinkedList<T> };

This example assumes that --strictNullChecks is turned off, otherwise it's indeed impossible to create and object like this without violating type constraints - this type describes an infinite data structure if next is not allowed to be undefined.

But if you declare next as either a reference to the next item in the list or undefined, everything is fine:

type LinkedList<T> = T & { next: LinkedList<T> | undefined };

type Person = { name: string };

const personList: LinkedList<Person> =
        { name: 'Head', next: { name: 'Last', next: undefined } };

Upvotes: 0

Related Questions