Search code examples
typescripttypescript2.0

TypeScript check for empty string


Is there a way for TypeScript to statically check for an empty string? Is there a way to statically require a non-empty string to be passed to a function?

let fn = function(a:string){

};

fn('');

or

let a = '';
fn(a);

Can TS help us here?


Solution

  • I believe this is as close as you're going to get only using the typing system (rather than having a 'nonEmptyString' class)

    type nonEmptyString = never; // Cannot be implicitly cast to
    function isNonEmptyString(str: string): str is nonEmptyString {
        return str && str.length > 0; // Or any other logic, removing whitespace, etc.
    }
    

    Testing it:

    let fn = function(a: nonEmptyString) {
    
    }
    
    let someStr = '';
    if (isNonEmptyString(someStr)) {
        fn(someStr); // Valid
    } else {
        fn(someStr); // Compile error
    }
    

    Unfortunately, you end up with warts since nonEmptyString is never. Which means you need to explicitly cast nonEmptyString back to string.

    let fn = function(a: nonEmptyString) {
        let len = a.length; // Invalid
        let len2 = (<string>a).length; // Valid
        let str = a + 'something else'; // Valid (str is now typed as string)
    }
    

    One possible resolution is:

    type nonEmptyString = string & { __nonEmptyStr: never };
    

    Which alleviates the problem of having to explicitly cast back to a string (all three tests above are valid), but does pollute the type with __nonEmptyStr (which will be undefined if referenced).