Holger Holger - 1 month ago 8
TypeScript Question

Generic Type Variable with type narrowing

Is this behaviour a bug in Typescript 2.0.3? How could i improve the function definition?

function cleanString<T>(path: T): T {
if (path === null || path === undefined || typeof path !== 'string') {
return path;
}
return path.replace(/\\+/g, '/'); // <- path is never here
}


Expected behavior:
Should compile with no issue

Actual behavior:
path
is
never
in the last line.

function tchmi_path(path: any)


would work, but looses the (input type == output type) information.

(<any>path)
works, but is not elegant.

Based on Nitzan Tomer ideas i found:

function tchmi_path<T>(path: T): T;
function tchmi_path(path) {
if (typeof path === 'string') {
return path.replace(/\\+/g, '/').replace(/\/+/g, '/').replace(/^\/+/g, '');
}
return path;
}

Answer

You'll need to do some casting:

function cleanString<T>(path: T): T {
    if (path === null || path === undefined || typeof path !== 'string') {
        return path;
    }

    return (path as string).replace(/\\+/g, '/') as any;
}

let num = cleanString(3); // type of num is number
let bool = cleanString(true); // type of bool is boolean
let str = cleanString("string"); // type of str is string

(code in playground)


Edit

If you don't like the use of any, and if T can be a limited set of types, then you can do:

function clean(path: string): string;
function clean(path: boolean): boolean;
function clean(path: number): number;
function clean(path) {
    if (typeof path === "string") {
        return path.replace(/\\+/g, '/');
    }

    return path;
}

let num = clean(3); // type of num is number
let bool = clean(true); // type of bool is boolean
let str = clean("string"); // type of str is string

(code in playground)

Comments