DEV Community

Advanced TypeScript Exercises - Answer 2

Pragmatic Maciej on February 12, 2020

In the question I have asked why below snippet doesn't compile type User = { id: number; kind: string; }; function makeCustomer<T extend...
Collapse
 
nmonastyrskyi profile image
Nikita Monastyrskiy

Good explanation, thanks!

Collapse
 
tugbayatilla profile image
Tugbay Atilla • Edited

Thanks for the good examples.

for the bug, i would say, we are overriding "kind" member with 'customer' no matter what. So the solution could be like checking if the kind member given by the argument. I would not call this as bug, i was expecting this behavior actually :)

function makeCustomer<T extends User>(u: T): T {
    return {
    ...u,
    id: u.id,
    kind: u.kind ?? 'customer' // <-- here is the changed part
  }
}

const admin = makeCustomer({ id: 1, kind: 'admin' } as Admin)
console.log(admin); // {id: 1, kind: "admin"}
Enter fullscreen mode Exit fullscreen mode

but also the important thing is what is the expectation from the function. function says, makeCustomer, does not matter we are assigning to kind 'admin', 'hooman', or 'animal', eventually it sounds like we are making a customer :)
yet, it was good example :)

Collapse
 
tmcrs123 profile image
Tiago Miguel Costa Rodrigues

Thank you for putting together these exercises, they are really great for learning purposes!

I have a question regarding the bug you mention please. Isn't TS assuming the wrong kind because in makeCustomer you are overwriting the kind to be customer ?

Wouldn't the following solve the bug?

function makeCustomer<T extends User>(u: T): T {
    return {
    ...u, // spread all properties of u being T
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
macsikora profile image
Pragmatic Maciej

That would indeed fixed the issue, but the idea was to have constructor of the customer. Besides sense of this function (which is discussable) we can fix it by saying we will return specific kind. Pay attention that I needed to omit kind property from Admin type as having a join between {kind:'a'} & {kind: 'b'} creates never type as there is no intersection between them. Here is the code - typescriptlang.org/play?#code/C4Tw...

Collapse
 
nombrekeff profile image
Keff

Cool, I didn't realize about the bug you mentioned, makes sense, thanks for sharing :)

Collapse
 
macsikora profile image
Pragmatic Maciej

Thanks for the great answer you have given!

Collapse
 
nombrekeff profile image
Keff

A pleasure, it's a great way to improve my knowledge about TS.

I will be recommending this series to some of my colleagues.

Collapse
 
macsikora profile image
Pragmatic Maciej

Type is Admin but the structure which is returned has kind property with value customer, so its not valid member of the type Admin.