DEV Community

Discussion on: Advanced TypeScript Exercises - Question 2

Collapse
 
nombrekeff profile image
Keff • Edited

Cool, it took me a little to figure this one out. I've made a Gist to hold the answer as to not spoil other people!

Gist Here

Anser From Gist:

PD: I don't know if it's the correct answer, but it's what I would have done :)

I think it fails because we always expect the output type to be equal to the generic type, although we always return a User.

Typescript tells us that if we pass in a generic type, for example:

createCustomer<{  id: number, kind: string, other: number }>({ 
  id: 1, 
  kind: 'customer' 
});
// >> This gives an error, "Property 'other' is missing in type"
Enter fullscreen mode Exit fullscreen mode

If the above Generic is passed, the return type expects to also contain other property.

So to solve this we could:

  • Pass in all additional parameters to return (preferred)
function makeCustomer<T extends User>(u: T): T {
  return {
    ...u,
    id: u.id,
    kind: 'customer',
  };
}
Enter fullscreen mode Exit fullscreen mode
  • Set the return type always to User
function makeCustomer<T extends User>(u: T): User {
  return {
    id: u.id,
    kind: 'customer',
  };
}
Enter fullscreen mode Exit fullscreen mode
  • Mark the output objects as T
function makeCustomer<T extends User>(u: T): T {
  return {
    id: u.id,
    kind: 'customer',
  } as T;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dwjohnston profile image
David Johnston

I think it fails because we always expect the output type to be equal to the generic type, although we always return a User.

Ah, of course.

Mark the output objects as T

I think this is a bad option, as it's possible that you would be now expecting an extra field to be there, that no longer exists.

Collapse
 
nombrekeff profile image
Keff

I think this is a bad option, as it's possible that you would be now expecting an extra field to be there, that no longer exists.

Agreed, this is why I marked the first option as preferred :P

Collapse
 
mateiadrielrafael profile image
Matei Adriel

I think u could also do a ...u inside the return

Collapse
 
macsikora profile image
Pragmatic Maciej

Mangola, link is broken please fix it :)

Collapse
 
nombrekeff profile image
Keff • Edited

Ohh sorry, fixed, I shared the edit link