Description
Introduction
Currently, type literals are capable of representing any instantiated (non-generic) type except those that are recursive. This is because, as an anonymous type, they do not have a name with which to create this type.
This proposal covers recursive type literals. These type literals add the additional ability of the literal referring to itself. This has one main advantage: emitting .d.ts files for expressions typed by class expressions now have a "flattened" representations. As class expressions could easily have recursive components, we'd like to be able to emit a corresponding type representation into the .d.ts file without contaminating the namespace with additional fresh type names.
Design
var x : <Node> { next: Node; value: number; };
The above acts similarly to this example:
interface Node { next: Node; value: number; };
var x : Node;
with one critical exception: in the first example the 'Node' name is not visible outside of the type literal.
Typechecking
Typechecking of recursive type literals works just as recursive interfaces, with the exception (as mentioned above) that the name given to the recursive type literal is not visible in the lexical scope outside of the type literal. Otherwise, these expand and are compared for equality structurally just as interfaces.
Differences with other designs
This design differs from similar designs, named the 'self' type design where there is a specific keywords that the type can refer to its self. This proposal is strictly more expressive, albeit at the cost of some additional syntax. For example, embedded recursive types are possible:
var x: <Node> { up: <Parent>{ up: Parent; node: Node}; next: Node; value: number};