26

In the Typescript definition file (DefinitelyTyped) I am examining, there is an interface, a function and a namespace all with the exact same name: twilio.

Here is the sample, from the first few lines of the file:

declare interface twilio {
  (sid?: string, tkn?: string, options?: twilio.ClientOptions): twilio.RestClient
}

declare function twilio(sid?: string, tkn?: string, options?: twilio.ClientOptions): twilio.RestClient;

declare namespace twilio {
 ....

Then all the way at the bottom of the file it says

export = twilio;

Well which one is it exporting? The interface? The function? the namespace? How does this make any sense? How can you name multiple things the exact same nae in the same scope/namespace ??

Community
  • 1
  • 1
CodyBugstein
  • 21,984
  • 61
  • 207
  • 363
  • 4
    Take a look at [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) - it's exporting everything - I wouldn't have used the interface call signature. It's more clear to just have overloaded functions. (No time for a full answer) – Gerrit0 Jan 18 '18 at 06:28
  • @Gerrit0 Id understand if the signatures were different, but the interface and the declared function have the same exact signature. Besides the type created by the interface is never actually used. One of the two is redundant, correct? – Knu Jan 15 '19 at 16:14
  • also you will receive a lot of fun when you try to use typeof operator with a merged type declaration, looks like it has some hierarchy in which it should return the types for that operator, but it is unknown thus unpredictable. – fires3as0n Nov 11 '22 at 21:39

4 Answers4

1

Expand @ppp answer

Declaration merging is when the TypeScript complier merges two or more types into one declaration provided they have the same name.

Important thing to remember is: class with class cannot be merged.

So just for example is allowed to merge:

interface User {
  name: string;
}

interface User {
  age: number;
}

interface User {
  height: number;
}

class Person implements User {
  name = "John"
  age = 30;
  height = 180
}

enum User {...}

namespace User {...}

const person = new Person();
console.log(person) // {name: "John", age: 30, height: 180}

export person;

So to answer to your question you can export single type like in the example above the rest of the declaration are merged between them

0

Basically, it defines something which all off the above at the same time. I add a new answer to give you a link to ts playground and I hope that it helps you.

Pang
  • 9,564
  • 146
  • 81
  • 122
JGoodgive
  • 1,068
  • 10
  • 20
0

The official typescript doc calls this "declaration merging".

ppp
  • 9
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 22 '22 at 15:23
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/30882061) – Andrew Halil Jan 29 '22 at 09:31
-2

They have just created a runner-run-sportsbag thingamagig. Its ok, its not your code. Basically they export a thing that is all of the above. Just like you could do this in javascript:

function foo() {};
foo.bar = function() {};

look at this ts playground code

JGoodgive
  • 1,068
  • 10
  • 20
  • But they're not simply exporting an object with a bunch of properties. They're creating many things with the same name – CodyBugstein Jan 18 '18 at 14:24
  • They are not really creating anything. They are declaring shapes of things. There is a shape called twilio that fits all of the uses described and it is there to help typescript understand what it is currently working with. If you ever use the actual namespace the implementation will be a function with the specific type and arguments, it will have a property that is also a function and it have all the stuff exported properties described in the namespace. So its a function-functionContainer-propertyBucket thing. But the declarations are just that.. declarations of what will exist. – JGoodgive Jan 18 '18 at 19:21
  • But there are three compeltely different "things" declared to be `twilio`. It's not like there's a just a shape definition and then an implementation. That I would get. This has 3 separate declarations – CodyBugstein Jan 18 '18 at 21:13
  • I dont get it. I keep answering you here in the comments and it gets deleted or something? 3rd time: They are no "things" they are like the shapes of things. So what they say is that if there is a real "twilio" thing then that thing would be a function that has another function property as well as a collection of other properties on it. That thing would be a function-functionBag-propertyBag thing. – JGoodgive Jan 18 '18 at 21:48
  • 1
    (Maybe your internet connection is buggy? ) Ok so translated to English, the declarations mean "if someone makes a function called twilio, it will look like this, and if it's an interface, it will look like this, and if it's a namespace it will look like this" ? – CodyBugstein Jan 18 '18 at 22:26