0

In .net/c#, you can define an extension method like this:

public static bool IsBlank(this string s)
{
   return String.IsNullOrEmpty(s);
}

and call it like this:

string myString = null
if(myString.IsBlank()) ...

This is extremely useful for dealing with strings that may be null.

In Typescript and javascript, I would very much like to do the same thing, something like this:

String.prototype.isBlank = function ()
{
    return this === null || this === undefined || this == '';
}

var myString: string = null
if(myString.isBlank()) ...

but it doesn't work, because javascript doesn't know anything about the fact that myString is typed as string, or was in the Typescript file, anyway. So you get an error like 'isBlank' is not a member of null.

The only real workaround is something klunky like if((mystring || '').isNotBlank()), but that gets tedious (and error prone).

In javascript, is there any way to extend null itself so that a call like null.coerce(defaultValue) would work?

If not, is there a way to cause typescript to transpile null.coerce(defaultValue) into (null || defaultValue)?

Update: I know I could always write coerce(variable, defaultValue), but I think that's an even more klunky syntax.

Update 2: My simple code snippet was too simple to illustrate the use case, as vanilla javascript has simple workarounds, as some answers said.

In a real application, suppose I get a complex table object back from some API call, and I want to write something like:

var x = result.rows[i].field[j].parseAsInt(0).toString()

because rows(i, j) is some legacy field that's an integer, but they stored it as a string so they could use "-" instead of null or zero, but sometimes they DO use null, and I have to deal with it by mapping any such thing to zero. My parseAsInt method would be something that says "if it's parseable as an integer, return the integer, otherwise ("-", null, undefined) the specified default value. The alternative would be

var x = (result.rows[i].field[j] || 0).parseAsInt(0).toString()

and that is a more awkward syntax.

Joshua Frank
  • 13,120
  • 11
  • 46
  • 95
  • I hope, you can find answer here: (https://stackoverflow.com/questions/6003884/how-do-i-check-for-null-values-in-javascript) – Vishwak Dec 13 '19 at 17:43
  • No, that's about how to check for null. I'm trying to do so with a better syntax. – Joshua Frank Dec 13 '19 at 17:45
  • Your code should fail at compile time, with "null is not assignable to type string". – ASDFGerte Dec 13 '19 at 17:48
  • @ASDFGerte: that was just an example to make the point. In a real application, the string would be something more unknown, like `result.rows[i].field[j]`, returned via some API call that queries a database with a nullable column. – Joshua Frank Dec 13 '19 at 17:51
  • If it's a string, and not null, your described method works. I don't get it. – ASDFGerte Dec 13 '19 at 17:51
  • @ASDFGerte: that also depends on the TypeScript compiler settings (you _can_ have it accept `null` as a `string`, though I personally recommend `--strictNullChecks`). – Jacob Dec 13 '19 at 17:52
  • Yes, though i've had strict null checks on from the moment they were introduced, and haven't regretted it a single moment. As a sidenote, there is also always the way of not using the prototype (no extension), but just e.g. `lib.isBlank(myString)` or `myString |> lib.isBlank`. Also note, that i take the example as just that, an example, because when it is already clear, that it's a string, writing if(myString) is probably the shortest for "not empty" anyways. – ASDFGerte Dec 13 '19 at 17:59
  • @ASDFGerte: I added a more realistic code sample, to illustrate why I'd like this feature. – Joshua Frank Dec 17 '19 at 16:18

1 Answers1

0

That is beyond the capabilities of TypeScript at present.

It should be noted that this specific extension method you're wanting to create is probably not needed; in JS both null and '' are falsy, so you really only need to do:

if (myString) {
  // ...
}

...to get the behavior you illustrated. In other cases, the ?. operator is a handy way to handle attempts to call null and undefined values, but there still isn't the ability to do a true extension method, and null has no prototype so you can't use a prototype extension either.

Jacob
  • 77,566
  • 24
  • 149
  • 228
  • Perhaps trying to reopen the feature suggestion with the TypeScript folks would be helpful. Looks like it has been discussed in the past: https://github.com/microsoft/TypeScript/issues/9 – Jacob Dec 13 '19 at 17:47
  • In this case, the desired return value is boolean, so that's true. But in other situations, it would be nice to return other types, so that they could be chained, e.g. in a fluent syntax. But let me look at that feature you linked to. – Joshua Frank Dec 13 '19 at 17:48
  • The only way a full extension method that can have `this` set to `null` could work in the JavaScript runtime is if TypeScript converted calls to that extension method to some static function call, like transpiling `myString.isBlank()` to `String.isBlank(myString)`. Seems like something that should be doable by the compiler, so probably not an unreasonable ask. – Jacob Dec 13 '19 at 17:55
  • `var x = (input) => {return toString.call(input) === '[object Undefined]' || toString.call(input) === '[object Null]'|| input === '' ? true : false} x(''); true` I hope this works – Vishwak Dec 13 '19 at 18:22