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

Unable to add property to interface after external import #1574

Closed
eschwartz opened this issue Dec 30, 2014 · 2 comments
Closed

Unable to add property to interface after external import #1574

eschwartz opened this issue Dec 30, 2014 · 2 comments
Labels
Question An issue which isn't directly actionable in code Revisit An issue worth coming back to

Comments

@eschwartz
Copy link

Consider this code:

// myPlugin.ts
<reference path="typings/jquery/jquery.d.ts" />

// Add a plugin to the JQuery type
interface JQuery {
  myPlugin():JQuery;
}

var $myEl = $('foo').myPlugin();
var $bar = $('foo').find('bar');

This works fine. The problem comes when I mix this with an external import:

// myPlugin.ts
<reference path="typings/jquery/jquery.d.ts" />

import _ = require('underscore');

// Add a plugin to the JQuery type
interface JQuery {
  myPlugin():JQuery;
}

var $myEl = $('foo').myPlugin();
var $bar = $('foo').find('bar');
/// error TS2339: Property 'find' does not exist on type 'JQuery'.

This does not seem to be specific to JQuery/underscore, but happens whenever I add to an interface in the same file as an import.

I can work around this by moving the interface additions to another file:

// jquery.ext.d.ts
<reference path="typings/jquery/jquery.d.ts" />

interface JQuery {
  myPlugin();
}

// myPlugin.ts
<reference path="typings/jquery/jquery.d.ts" />
<reference path="jquery.ext.d.ts" />

import _ = require('underscore');

var $myEl = $('foo').myPlugin();
var $bar = $('foo').find('bar');

Is this a bug in the compiler, or expected behavior? If it is expected, is there any documentation I can look at?

Thanks!

@RyanCavanaugh RyanCavanaugh added Question An issue which isn't directly actionable in code Revisit An issue worth coming back to labels Dec 30, 2014
@RyanCavanaugh
Copy link
Member

This is the expected behavior.

When a file has a top-level export or import, that file becomes a new 'namespace' that is the external module the file represents. The net effect is similar to this:

module My_File { // <- Internal name created by the compiler
  interface JQuery { ... } // A new type, not an extension of JQuery
}

We need to document this in an easier to find place as it's a very frequently-encountered thing (I've seen many questions on StackOverflow and here).

@eschwartz
Copy link
Author

Thanks. Yes, some documentation on this would be helpful. I looked through a number of StackOverflow posts specifically about adding properties to interfaces, but I can't find anything about it in the docs. The only reference I found to this functionality is in a blog post from Jan 2013:

Extending Existing Types

Moreover, interfaces in TypeScript are open, meaning you can add your own members to an interface by simply writing another interface block. If you have an external script that adds members to Date, for example, you simply need to write interface Date { /.../ } and declare the additional members.

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 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 Revisit An issue worth coming back to
Projects
None yet
Development

No branches or pull requests

2 participants