Is there a way to add a isNullOrEmpty(str:string) to the static string object.
such that I can call it:
String.isNullOrEmpty(myobj);
I have found a way to put it on the implementation but that does not help for a method such as this.
Is there a way to add a isNullOrEmpty(str:string) to the static string object.
such that I can call it:
String.isNullOrEmpty(myobj);
I have found a way to put it on the implementation but that does not help for a method such as this.
String
is defined in lib.d.ts
with the following interface
interface StringConstructor {
...
}
declare var String: StringConstructor;
so while you can't add methods to a variable, you can add them to the interface, using
interface StringConstructor {
isNullOrEmpty(str:string):boolean;
}
and them implement them on the variable, using
String.isNullOrEmpty = (str:string) => !str;
TypeScript does something called declaration merging, which is explained in section 10.5 of the spec.
The gist of it is you can put members in module foo, and then later on put more members in module foo. As of 0.9 this extends to putting members in the namespace of a class as well, as long as the class is declared first. That's a new feature and I've discovered bugs around it, but it's supposed to work.
So to answer your question specifically you can just do this:
module String {
export function isNullOrEmpty(s: string): boolean {
return !s;
}
}
var s: string;
alert(String.isNullOrEmpty(s).toString()); // true
s = "";
alert(String.isNullOrEmpty(s).toString()); // true
s = "asdf";
alert(String.isNullOrEmpty(s).toString()); // false
Apparently my answer is not complete because String is declared as a var and not a module. Declaration merging doesn't carry over to vars (as of 0.9) which is annoying. There is still a way around this though it's a bit of a hack:
// filea.ts
module String {
export function isNullOrEmpty(s: string): boolean {
return !!s;
}
}
module mynamespace {
export declare var String: {
new (value?: any): String;
(value?: any): string;
prototype: String;
fromCharCode(...codes: number[]): string;
isNullOrEmpty(s: string): boolean;
}
}
// fileb.ts
/// <reference path="filea.ts" />
module mynamespace {
var s: string;
String.isNullOrEmpty(s); // true
s = "";
String.isNullOrEmpty(s); // true
s = "asdf";
String.isNullOrEmpty(s); // false
}
What's going on in filea
is you're putting a function on the var String, and then declaring that mynamespace.String
exists with everything String in lib.d.ts has plus what you added. Then, so long as you're working in mysnamespace
, references to String will assume you're talking about mynamespace.String
. That doesn't really exist so you'll get good ol' String which is what you want.
Like I said it's a bit dirty, but assuming you're following decent namespace conventions you should have a top level namespace where you only have to do this once. If you want to share the String extensions as part of a library though... well you're stuck.
My solution use different approach, because string
base type in this phase cannot be extended.
module Type {
"use strict";
export module BaseType {
export class ApplicationString {
/**
* Indicates whether the specified string is null or an Empty string.
*
* @property string inputString
* @see https://msdn.microsoft.com/en-us/library/system.string.isnullorempty(v=vs.110).aspx
*/
static isNullOrEmpty(inputString: string): boolean {
if (inputString === null || inputString.length === 0) {
return true;
} else {
return false;
}
}
}
}
}
alert(Type.BaseType.ApplicationString.isNullOrEmpty(null));
alert(Type.BaseType.ApplicationString.isNullOrEmpty(""));
alert(Type.BaseType.ApplicationString.isNullOrEmpty("text"));
Demo: TypeScriptPlayground