Skip to content

Suggestion: Interfaces as string literals #2902

Closed

Description

I have been looking at dependency injection and a few issues with refactoring in regards to _.pluck. One of the primary things I run into is that I want these things to enforce the interface for refactoring.

A few examples

Interface used as a symbol for dependency injection

interface IExampleInterface {
  interfaceProperty: string;
}

function angularInjection(...fields: string[]) {
  return (target: Function) {
    target.$inject = fields;
  }
}

@angularInjection(nameof(IExampleInterface));
class Controller {
  constructor(injectedExample: IExampleInterface) {
  }
}

would compile to

function angularInjection() {
    var fields = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        fields[_i - 0] = arguments[_i];
    }
    return function (target) {
        target.$inject = fields;
    };
}
var Controller = (function () {
    function Controller(injectedExample) {
    }
    Controller = __decorate([
        angularInjection('IExampleInterface')
    ], Controller);
    return Controller;
})();

In the case of an interface like pluck we could do something like this

interface IExampleInterface {
  prop: string;
}

var items: IExampleInterface[] = [{prop: 'test1'},{prop: 'test1'}];
var props: string[] = _.pluck(items, nameof(IExampleInterface.prop));

would compile to

var items = [{prop: 'test1'}, {prop: 'test1'}];
var props = _.pluck(items, 'prop');

In this way we could enforce some level of type safety in common javascript reflection use cases.

Activity

  1. RyanCavanaugh commented on Apr 24, 2015

    @RyanCavanaugh
    Member

    Are we basically talking about C#'s nameof operator?

  2. park9140 commented on Apr 24, 2015

    @park9140
    ContributorAuthor

    Hadn't used it before but seems right.

  3. danquirk commented on Apr 24, 2015

    @danquirk
    Member

    Is this a dupe of #394 then?

  4. park9140 commented on Apr 25, 2015

    @park9140
    ContributorAuthor

    Dan Quirk (@danquirk), seems like this is different.

  5. park9140 commented on Apr 25, 2015

    @park9140
    ContributorAuthor

    Dan Quirk (@danquirk), seems to me that the initial suggestion on #394 is quite different. This nameof methodology is primarily aimed at elmination of magic strings that cannot be refactored. Specifically the pluck use case isn't solved by checking the literal argument. The proposal in #394 is dangerous as noted in some of the comments and would either need runtime gating or to prevent all non literal strings from being parameters to a method describe with the memberof methodology. It also does not handle using Interface names for injection purposes as the nameof methodology would.

  6. alex1kirch commented on May 12, 2015

    @alex1kirch

    I fully agree with Jonathan Park (@park9140).
    Also, the nameof methodology can be used when working with Object.observe() method.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe

    // A user model
    var user = {
      id: 0,
      name: 'Brendan Eich',
      title: 'Mr.'
    };
    
    // Create a greeting for the user
    function updateGreeting() {
      user.greeting = 'Hello, ' + user.title + ' ' + user.name + '!';
    }
    updateGreeting();
    
    Object.observe(user, function(changes) {
      changes.forEach(function(change) {
        // Any time name or title change, update the greeting
        if (change.name === nameof(user.name) || change.name === nameof(user.title)) {
          updateGreeting();
        }
      });
    });
  7. mhegazy commented on Dec 10, 2015

    @mhegazy
    Contributor

    looks like another duplicate of #3628

  8. locked and limited conversation to collaborators on Jun 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions