Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to narrow arguments with a union type?

I have an argument that is number | string, and try to derive a variable that is a number.
The following code shows what I expected to work. (That kind of thing would work in Python.)

function kg_to_lbs(arg: number | string) {
    let is_number = typeof arg === 'number';
    let arg_number: number = is_number ? arg : parseInt(arg);  // two errors
    return arg_number * 2.20462;
}

To my surprise TypeScript is so strict about types, that it does not allow my solution:

The argument passed to parseInt is not trusted to be a string:   (error TS2345)
Argument of type 'string | number' is not assignable to parameter of type 'string'.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

And the result assigned to arg_number is not trusted to be a number:   (error TS2322)
Type 'string | number' is not assignable to type 'number'.

Is there a usual way to do this in TS?
Or is there a way to tell TS, that I am sure what type something is?

>Solution :

The usual way is to inline the condition:

function kg_to_lbs(arg: number | string) {
    let arg_number: number = typeof arg === "number" ? arg : parseInt(arg);
    return arg_number * 2.20462;
}

I wonder if there is some trick to still write it in two lines

You could use a custom type predicate, but these must be functions:

function isNumber(arg: any): arg is number {
  return typeof arg === 'number';
}

function kg_to_lbs(arg: number | string) {
    let arg_number: number = isNumber(arg) ? arg : parseInt(arg);
    return arg_number * 2.20462;
}

BTW, in this particular case, you could have simply written:

function kg_to_lbs(arg: number | string) {
    return arg * 2.20462;
}

since the * operator converts its operands to numbers, and converting a string to a number parses it 🙂

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading