Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorating interface methods. #6818

Closed
d180cf opened this issue Feb 2, 2016 · 6 comments
Closed

Decorating interface methods. #6818

d180cf opened this issue Feb 2, 2016 · 6 comments
Labels
Duplicate An existing issue was already created Needs More Info The issue still hasn't been fully clarified

Comments

@d180cf
Copy link

d180cf commented Feb 2, 2016

Sometimes it's useful to have methods with properties attached:

Foo.prototype.bar = bar;
bar.tag = 123;

The corresponding interface could look like:

interface Foo {
  @tagged
  bar(): void;
}
@RyanCavanaugh RyanCavanaugh added External Relates to another program, environment, or user action which we cannot control. Needs More Info The issue still hasn't been fully clarified and removed External Relates to another program, environment, or user action which we cannot control. labels Feb 2, 2016
@RyanCavanaugh
Copy link
Member

Please log issues with enough information for us to understand what's going on. How did tagged get turned into tag? Where did 123 go? What is stopping you from writing this code today?

@d180cf
Copy link
Author

d180cf commented Feb 2, 2016

@tagged is a decorator that is when applied to a method, adds a property called tag to it:

function tagged(proto, name, d: TypedPropertyDescriptor<any>) {
  d.value.tag = 123;
}

class FooImpl {
  @tagged
  bar() {
    console.log("bar");
  }
}

const foo = new FooImpl;
foo.bar.tag == 123;

Then if we try to come up with an interface definition for FooImpl we will find that it's difficult to express the fact that some methods in our interface have the tag property:

interface Foo {
  /** This method has .tag property attached. */
  bar(): void;
}

Having such a comment isn't good enough and the types intersections help us solve the problem to some extent:

type Tagged<T extends Function> = T & { tag: number };

interface Foo {
  bar: Tagged<() => void>;
}

This is pretty good until we decide to extend our class with an overloaded version of bar and the overloaded version needs to appear in a separate file that extends the interface:

/// [file1.ts]
interface Foo {
  bar: Tagged<() => void>;
}

/// [file2.ts]
interface Foo {
  bar: Tagged<(abc: string) => void>;
}

But this doesn't work because bar is declared as a member, not as a method. With an ambient decorator it should be possible:

/// [file1.ts]
interface Foo {
  @tagged
  bar(): void;
}

/// [file2.ts]
interface Foo {
  @tagged
  bar(abc: string): void;
}

@mhegazy
Copy link
Contributor

mhegazy commented Feb 2, 2016

a decorator on an interface does not make much sense. it is an implementation detail, and has no impact on the type anyways. adding the tag to the interface makes it impossible for you to implement it, as again the decorator does not do any type mutations. i think what you are looking for is: #4881

@mhegazy mhegazy added the Duplicate An existing issue was already created label Feb 2, 2016
@mhegazy mhegazy closed this as completed Feb 2, 2016
@jossiwolf
Copy link

@mhegazy Can you elaborate on why this doesn't make much sense?

One use case could be something like Retrofit for Android:

interface MyAPI {

   @GET("/example")
   getExampleData(): Observably<ExampleModel>;

   @POST("/example")
   postExampleData(body: ExamplePostModel): Observable<ExamplePostResponseModel>;
}

Do you have any idea how this could be done without interface member decorators?

@kitsonk
Copy link
Contributor

kitsonk commented Jun 29, 2017

Both of those decorators imply some sort of implementation/run-time meta data coupled with an interface. They are fully erasable type information, not implementations. What makes sense about that?

Do you have any idea how this could be done without interface member decorators?

Decorators on a class implementation?

@IlyaGulya
Copy link

Any progress? I need them exactly for this purpose #6818 (comment)

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created Needs More Info The issue still hasn't been fully clarified
Projects
None yet
Development

No branches or pull requests

6 participants