DEV Community

Pragmatic Maciej
Pragmatic Maciej

Posted on • Edited on

9 1

Advanced TypeScript Exercises - Question 3

Hello again. Today's question is about typing function with two arguments being union type. The goal is to block possibility to pass mixed types into arguments, so if the first argument is a number then second also needs to be number, in other words there is dependency between arguments which we need to write.

function f(a: string | number, b: string | number) {
    if (typeof a === 'string') {
        return a + ':' + b; // no error but b can be number!
    } else {
        return a + b; // error as b can be number | string
    }
}
f(2, 3); // correct usage
f(1, 'a'); // should be error
f('a', 2); // should be error
f('a', 'b') // correct usage
Enter fullscreen mode Exit fullscreen mode

The whole code can be found in the playground

There is not one possibility of correct typing, can you solve this puzzle in many ways? Is it possible to type it without using type assertions? Post your answers in comments. Yes you can change the implementation also, the key is to have the same behavior + type safety. Have fun! Answer will be published soon!

This series is just starting. If you want to know about new exciting questions from advanced TypeScript please follow me on dev.to and twitter.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (7)

Collapse
 
kashyaprahul94 profile image
Rahul Kashyap • Edited

A quick idea -

function f<T extends string | number>(a: T, b: T) {
    if ( typeof a === "string" ) {
        return a + ':' + b; // no error but b can be number!
    } else {
        return a as number + (b as number); // error as b can be number | string
    }
}

f(2, 3); // correct usage
f(1, 'a'); // should be error
f('a', 2); // should be error
f('a', 'b') // correct usage

Playground link

Collapse
 
macsikora profile image
Pragmatic Maciej

Nice, thanks but your code still doesn't compile, can you make a version which compiles? - Playground

Collapse
 
kashyaprahul94 profile image
Rahul Kashyap

Updated the answer :)

Thread Thread
 
macsikora profile image
Pragmatic Maciej • Edited

Now the interface of the function works in reverse way, what is correct is incorrect 😉

Thread Thread
 
kashyaprahul94 profile image
Rahul Kashyap • Edited

If i understood it correct, we are not allowed to change implementation of the method, just introduce types to make it work, right ?

Thread Thread
 
macsikora profile image
Pragmatic Maciej

Yes, implementation of the value level can stay, but assertion like as X is a type level. Currently implementation cannot compile because of lack of proper typing, there is a way to solve it without any assertion that is why I left it as it is, so with compile error.

You can modify the implementation, the key is to have it working as original + typed safe.

Collapse
 
timon profile image
Timon van Spronsen • Edited

Another great challenge! I thought it'd be rather straight forward, but I've been sitting on this for at least 30 minutes and I don't have a solution yet. I'll give it another go tomorrow :)

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

Best practices for optimal infrastructure performance with Magento

Running a Magento store? Struggling with performance bottlenecks? Join us and get actionable insights and real-world strategies to keep your store fast and reliable.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️