Skip to content

Function instead of interface name when using Reflect #10711

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

Closed
pooyaho opened this issue Sep 5, 2016 · 4 comments
Closed

Function instead of interface name when using Reflect #10711

pooyaho opened this issue Sep 5, 2016 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@pooyaho
Copy link

pooyaho commented Sep 5, 2016

Hi
I've a problem with using reflect in field decorators. I've created a decorator with below signature:

export function Inject() {
    return function (clazz, name) {
        .......
        let typeName: string = Reflect.getOwnMetadata("design:type", clazz, name).name;
        .........
    }
}

class MyClass{
    @Inject()
    private $q:ng.IQService
}

And I use @Inject on fields. It works when field type is class but when field type is interface, it returns Function not the name of interface. How can I fix it?

@mhegazy
Copy link
Contributor

mhegazy commented Sep 6, 2016

TypeScript types, e.g. interfaces, type aliases, etc.., do not exist at runtime. they are design-time constructs that the compiler uses to check the consistency of the code, and are removed when generating the final JS.

The refectMetaData feature only preserves metadata about runtime values. classes do have a runtime value, i.e. the constructor function, whereas interfaces do not.

if the compiler knows there is a runtime value packaging the type (classes or enums), then it will use it; if not, it will try find the best "guess". so number will be Number, string will be String, [] becomes Array, async functions become Promise, and if your interface has a call or construct signatue on it, it will be Function, if none of these matches, it becomes Object.

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Sep 6, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Sep 6, 2016

you can find more relevant discussions in #3628

@mhegazy mhegazy closed this as completed Sep 6, 2016
@pooyaho
Copy link
Author

pooyaho commented Sep 7, 2016

I think my problem is about reflection not type checking, And I know all thing that you wrote. I want to know the interface name with reflection and nothing more. I want to replace Function in the below generated code to an string that contains name of interface.

class MyClass{
     @Inject
     private service:ng.IHttpService;
}

it compiles to

........
__decorate([
          Inject(), 
          __metadata('design:type', Function)
  ], MyClass.prototype, "service", void 0);
........

@mhegazy
Copy link
Contributor

mhegazy commented Sep 7, 2016

First, the interface name by itself is not sufficient. the name is not unique. Second, and more importantly, TS has a structural type system, not a nominal one, so the interface name is of inconsequential in this matter, you could pass in an anonymous type that matches the interface, or another interface, etc..

This issue has been discussed in length before, please see issue #3060 (linked from #3628 among others)

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

2 participants