Overlading functions

Topics: General
Oct 2, 2012 at 9:23 PM
Edited Oct 2, 2012 at 9:23 PM

Shouldn't this work according to the spec?

class SceneNode {
	getNode(index: number): SceneNode {
		...
	}

	getNode(name: string): SceneNode {
		...
	}
}

Instead, VS complains about the duplicate identifier "getNode".

Oct 2, 2012 at 9:28 PM

You need to do it this way: 

class SceneNode {
	getNode(index: number): SceneNode;
	getNode(name: string): SceneNode;
	getNode(key: any): SceneNode {
		return null;
	}
}

 


Oct 2, 2012 at 9:31 PM

Ok, and where do I define these declarations? And what's up with the third overload?

Thank you!

Oct 2, 2012 at 9:47 PM

So you define the overloads above your method definition (notice the semicolon at the end of the first two definitions.)  The third overload is the most important one because it defines what variables are available to the code within the method.  Notice that I've said there's a 'key' of type 'any'.  That's important because within the method you're going to need to check the type of that param before working with it.  Here's a more complete example:

class SceneNode {
	getNode(index: number): SceneNode;
	getNode(name: string): SceneNode;
	getNode(key: any): SceneNode {
		var node = null;
		if (typeof key === 'number') {
			// Find node by index
		} else {
			// Find node by name
		}
		return node;
	}
}

 

Oct 2, 2012 at 9:55 PM
Edited Oct 2, 2012 at 10:02 PM

Ok, thanks. So I have to check the type of the arguments myself. That's not really an imrovement over pure JS, though, is it? Won't plenty of type checks impact performance if the overloads are called often?

EDIT: just stumbled upon this discussion, which explains why it's not possible to do it the C++ way:

http://typescript.codeplex.com/discussions/397778

Oct 2, 2012 at 10:10 PM
Edited Oct 2, 2012 at 10:11 PM

The TypeScript guys (I work for Microsoft but I'm not a member of their team) try to keep the amount of magic they introduce into the generated code down to a bare minimum.  That means you still have to do what you would do in JavaScript in most cases.  To keep stuff like in your example to a minimum I've found that I just slightly change the way I approach writing my code.  In your example I would have simply created two seperate methods getNodeByName() and getNodeByIndex().  Anything in common between these methods I would have broken out to a third private helper method.  The advantage of that is that you don't need to do runtime checks like this because the compilers already done those checks for you. 

If you want to do it the JavaScript way where parameter types are more loose you certainly still can but you'll need to do the runtime checks you would traditionally have done in JavaScript.  Again... No magic added...

-steve

Oct 2, 2012 at 10:27 PM

Ok, I'll stick with the two separate methods then. Thanks again!