Open justinfagnani opened 6 years ago
Prior discussion at #4881
@RyanCavanaugh I am curious that whether decorators could be used to implement missing methods that are required by some interfaces. My app have some RTTI system which has this interface:
interface ITypeable {
readonly typeRep: TypeRep<any>;
is<T>(t:TypeRep<T>): this is T
}
And when writing implementation you have write a lot of boilerplate code:
const PrimGlyph_T = new TypeRep<PrimGlyph>("CLSID.PrimGlyph", GEL.IGlyph_T);
class PrimGlyph implements GEL.IGlyph {
public readonly typeRep = PrimGlyph_T
is<T>(t: TypeRep<T>) { return t.sub(PrimGlyph_T); }
}
I really hope that decorators could at least reduce these code into this
@RTTI("CLSID.PrimGlyph", GEL.IGlyph_T)
class PrimGlyph implements GEL.IGlyph {
}
Search Terms
decorator, metaprogramming, rename, renaming
Suggestion
As decorators near Stage 3, use cases are coming up that would currently pose problems for TypeScript due to their dynamic nature. Any additional properties added won't be visible, renamed properties won't analyze, and custom visibility schemes like protected or friends won't be understood.
This is another area where the dynamic nature of JavaScript might stretch the TypeScript type system, but with mapped and conditional types we might be able to describe a subset of the use-cases in the type system.
I don't have a concrete solution to suggest, but a couple of requirements that a solution should meet:
@observed
property)Mapped and conditional types already support some type transformation, but not transforming the keys, or describing a transformation across the static and instance types.
Maybe there's a way to expand on the list-comprehension-like syntax for mapped types to be even more like a list comprehension and allow
Here's a rough idea of a mapping that would transform a key name to a symbol, and filter by properties decorated with a specific decorator:
Symbol(P)
andwhere namespaced decorates P
are obviously very made up and probably not great choices choices.That's not exactly right for use from individual decorators though. Since decorators take and return an extended PropertyDescriptor, maybe we can just type the decorator itself:
(I threw in the
extends
type operator becausekey
must overridekey
inP
, so an intersection won't work. Some kind of object-spread-like syntax could also work)That describes that the key of the property is transformed, but it doesn't associate it with the declaration of that symbol.
One possibility for that is for TypeScript to understand the type of the
finisher
method on the property descriptor and use that to infer changes to the class itself:I realize I just put a lot of hand-wavy, complicated, probably not workable ideas up there, but maybe there's some better direction for the solution (short of adding an imperative type language) those could inspire.
Another approach would be for TypeScript to intrinsically understand the operation of a few well-known decorators as and not allow their definition within the type system itself.
Use Cases
One example of name-rewriting decorators is to prevent name collisions with string properties by renaming a property to a unique Symbol defined on the class:
Class A above would be equivalent to this manual namespacing:
Examples
Checklist
My suggestion meets these guidelines: