Skip to main content
Ben Nadel at jQuery NYC (Oct. 2009) with: Adam Sontag
Ben Nadel at jQuery NYC (Oct. 2009) with: Adam Sontag ( @ajpiano )

Using ANY Type Prevents Function Parameter Type-Checking In TypeScript 2.1.5

By on

I've been really enjoying TypeScript for its self-documentation nature and the way it forces me to think about data consumption within my application; but, I wouldn't say that I really understand TypeScript. Not yet. Every few days, I find myself tripping over some feature or caveat of the language. Just yesterday, I couldn't figure out why type-checking wasn't working for a particular method invocation; and, it wasn't until I read this issue over on GitHub that I learned that using an "any" type value - explicitly or implicitly - opts-out of function parameter type-checking in TypeScript.

Run this demo in my JavaScript Demos project on GitHub.

Normally, in TypeScript, if you define a function signature that accepts a certain type, such a String:

function( value: string )

... then, any attempt to pass-in a non-String value during function invocation should raise a type-checking error. But, it turns out, if the value that you're passing into the function is of type "any", then TypeScript does not enforce the type validation on the function parameter.

Now, that doesn't mean that the type constraint on the function parameter becomes useless - it's still used by TypeScript to validate the consumption of the argument within the body of the function. TypeScript just won't guarantee that the incoming value is actually the type defined by the function signature.

To see this in action, I've created a tiny demo in which we have a function that accepts a String argument and logs a few values to the console. I then attempt to invoke this function passing in a few different types:

  • String
  • Boolean
  • Any (explicitly up-cast from Date)

Let's look at the code:

// Passing a string to an :string argument.
logString( "I am a String" );

// Passing a Boolean to a :string argument - this will raise a type-checking error.
logString( true );

// Passing an ANY to a :string argument - this will NOT RAISE a type-checking error
// because ANY essentially "opts out" of type-checking.
// --
// Read More: https://github.com/Microsoft/TypeScript/issues/9999
logString( <any>( new Date() ) );

// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //

function logString( value: string ) : void {

	if ( value.toLowerCase ) {

		console.log( value.toLowerCase() );

	}

	// Even if we pass-in an ANY type, opting out of parameter type checking, the
	// :string type is still used to validate the parameter / value consumption
	// within the function body itself. As such, this guard statement will raise a
	// type-checking error because .getTime() is NOT a property of a String.
	if ( value.getTime ) {

		console.log( value.getTime() );

	}

}

Within the body of the function, you can see that I'm referencing two value properties: .toLowerCase() and .getTime(). The .toLowerCase() value is expected on a String; but, the .getTime() is not - it's a property of Date. I'm including the latter property in order to demonstrate that the String paremeter is still type-checked within the body of the function, even if the incoming value is not always validated.

When we run this code, we get the following output:

TypeScript doesn't type-check

As you can see, TypeScript raised a type-checking error when we attempted to pass "true" - a Boolean - into a function that expected a String. But, it did not raise a type-checking error when we passed <any>Date into the function. This is because the up-casting of the Date to an "Any type" essentially opts-out of type-checking for the function parameter. That said, we can see that TypeScript still uses the function parameter type annotation to validate the consumption of the argument within the body of the function.

Since TypeScript is still validating the argument within the context of the function, I don't think this behavior is such a big deal. Of course, you can always down-cast an "any" value to a concrete value before invoking the given function and TypeScript will validate the function invocation. That said, it's good to know that this "opt-out of type checking" behavior exists in TypeScript when dealing with "any" types.

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel