-
Notifications
You must be signed in to change notification settings - Fork 13k
Closed
Labels
In DiscussionNot yet reached consensusNot yet reached consensusSpecIssues related to the TypeScript language specificationIssues related to the TypeScript language specificationSuggestionAn idea for TypeScriptAn idea for TypeScript
Description
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
- Traceur and by extension AtScript (this proposal)
- Ember decorators
- Uses "- decoratorName(decoratorArgs, ...) decoratorTarget"
- Decorators can mutate the target class/field/argument(?). This proposal involves only inert metadata.
- tc-39 April 10 2014 Meeting Notes
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 consensusNot yet reached consensusSpecIssues related to the TypeScript language specificationIssues related to the TypeScript language specificationSuggestionAn idea for TypeScriptAn idea for TypeScript