Skip to content

Proposal: Annotations (alignment with Traceur/AtScript) #1557

Closed
@JeroMiya

Description

@JeroMiya

Summary

  • Implement annotations in TypeScript.
  • Align with Traceur and AtScript on syntax and ES5 representation.
  • Implement feature similarly to modules, with the following settings for output representation:
    • -annotations=none (default) - Annotations not supported by default. Produce compiler errors when used.
    • -annotations=atscript - Annotations encoded in the style of traceur/atscript (this proposal)
    • (future) -annotations=ecmascript - Hypothetically, if ES.Vnext were to adopt annotations, this would represent them using the approved ES7 annotation syntax, whatever that would be, as a bridge while TypeScript aligns with the official syntax (similar to how TS modules will transition).
  • In the long term, align with ECMAScript, if an annotation proposal is accepted.

Prior Art/Reference

Motivation

  • This proposal improves alignment between TypeScript and AtScript (and Traceur), improving interoperability between TypeScript code and code using these features of those compilers.
  • Annotations are useful in certain scenarios like dependency injection, domain driven design, decorator pattern, and more.

Differences from AtScript/Traceur

  • Run-time type metadata, runtime type checking, etc... is beyond the scope of this proposal.

Syntax and ES6 Representation

I am proposing the AtScript/Traceur syntax and ES6 representations, necessarily verbatim (minus the type annotations). An annotation can be applied to a function, a class, the constructor of a class, a field of a class, or a function argument:

function:

@MyAnnotation('argument')
function func() {}

// ES6 representation
function func() {}
func.annotate = [ new MyAnnotation('argument')];

A class:

  • Same representation as a function, of course.
@MyAnnotation('argument')
class MyClass {}

// ES6 representation
class MyClass {}
MyClass.annotate = [ new MyAnnotation('argument') ];

A constructor of a class:

  • Note: exactly the same as annotations on the class. Constructors are listed last in the list in the ES6 representation, after class annotations.
@MyClassAnnotation('argument')
class MyClass {
   @MyConstructorAnnotation('argument')
   constructor() {}
}

// ES6 representation
class MyClass {
  constructor() {}
}
MyClass.annotate = [ new MyClassAnnotation('argument'), new MyConstructorAnnotation('argument') ];

A field of a class:

  • Note: in AtScript/Traceur, the objects to the right of the field name also have an 'is' field at the same level as the 'annotate' field. I have omitted the 'is' fields below (RTTI is out-of-scope for this proposal).
class MyClass<T> {
  @MyFieldAnnotation('argument')
  field: T = null;
}

// ES6 representation:
class MyClass {
  field = null;
}
MyClass.properties = {
  'field': { annotate: [ new MyFieldAnnotation('argument') ] }
};

Arguments to a function:

  • Including arguments to constructors.
  • Note: In Traceur/AtScript, objects in the parameters array also have an 'is' field which is a reference to the type of the argument. That is omitted from the following examples (RTTI is out-of-scope for this proposal).
function func<T>(@MyFuncArgumentAnnotation('argument') arg: T): void {}

class MyClass<T> {
  constructor(@MyConstructorArgumentAnnotation('argument') arg: T) {}
}

// ES6 representation
function func(arg) {}
func.parameters = [ { annotate: [ new MyFuncArgumentAnnotation('argument') ] }];

class MyClass {
  constructor(arg) {}
}
MyClass.parameters = [ { annotate: [ new MyConstructorArgumentAnnotation('argument') ] }];

Extensions to lib.d.ts to support typing of annotations

  • e.g. adding 'properties', 'annotate', and 'parameters' field typings to Function interface.
  • Can be done by a third party/DT/etc... without changes to the compiler.

Metadata

Metadata

Assignees

Labels

In DiscussionNot yet reached consensusSpecIssues related to the TypeScript language specificationSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions