Web Development

Typescript: What’s This!?

Here’s a little innocuous looking typescript:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
export default class MyClass {
   public asStrings(
     array: Array<SomeObject>,       // array to turn to string
     objectReader: SomeObjectReader, // can extract a string from a SomeObject
   ) : string[] {
       const suffix = this.getSuffix();
 
       return array.map(objectReader.readStringFromObject)
           .map(str => str + suffix);
   }
 
   private static getSuffix() : string {
       return `_${new Date().getTime()}`;
   }
}

Let’s quickly understand what the above code is trying to do. It’s got a SomeObjectReader object that it can use to pull a string out of a SomeObject. It has an array of objects as input and it’s going to convert them all to string and suffix them all with a timestamp of some sort.

The static function to get the suffix should be static as it doesn’t rely on object state.

The asStrings function also could be static, but let’s ignore that for the moment as that’s not quite the focus of this discussion.

The above code has a minimum of two bugs!

You Can’t Use this to call a static function

Why my compiler let me do this is anyone’s guess. The getSuffix function must be called via the class name – MyClass.getSuffix().

I’ve just dropped a version of code into our dev environment that passed through all stages of compilation and test, yet still carried this bug. What a gotcha!

Functional Programming with this is Not Neat

In general we learn that x => myFunc(x) as a lambda in JavaScript can better be expressed as myFunc. This compares with Java where we use function references in place of full lambdas wherever possible.

So in the above code, the array map function is written .map(objectReader.readStringFromObject) which to the untrained eye (in other words, me) looks like we’re asking the readStringFromObject function on the particular instance of the object reader to be called within the map operation.

Is the above the equivalent of .map(obj => objectReader.readStringFromObject(obj)) ?

No.

If the objectReader is an instance of a class that uses this as part of its operation, then this doesn’t actually mean what you might hope it would mean in the more terse form. In the latter form, it works every time. In the first form, it might work, but it probably won’t.

What’s This?

In JavaScript, this is a relatively weak concept to begin with. In TypeScript it’s not practically any weaker, but it seems weaker as TypeScript gives us the illusion of concrete types and objects a lot more than its underlying transpiled code.

Aaagh!

Published on Java Code Geeks with permission by Ashley Frieze, partner at our JCG program. See the original article here: What’s This!?

Opinions expressed by Java Code Geeks contributors are their own.

Ashley Frieze

Software developer, stand-up comedian, musician, writer, jolly big cheer-monkey, skeptical thinker, Doctor Who fan, lover of fine sounds
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button