DEV Community

Discussion on: Default Props in React/TS - Part Deux

Collapse
 
ecyrbe profile image
ecyrbe

Hi Adam,

You may want to try this :

type Optionals<T extends object> = Required<Pick<T, Exclude<{
    [K in keyof T]: T extends Record<K, T[K]> ? never : K
}[keyof T], undefined>>>;

function setDefaults<Props extends object>(props: Props, defaults: Optionals<Props>): Required<Props> {
    return Object.assign({ ...props }, ...Object.keys(defaults).map(key => ({ [key]: props[key] ?? defaults[key] })));
}
Enter fullscreen mode Exit fullscreen mode

it's shorter, delegates type checking of optionals to the type Optionals<T>. I suggest you try the code to understand it. it needs typescript 3.8 (worth upgrading for ?. and ?? operators ).

Collapse
 
bytebodger profile image
Adam Nathaniel Davis

Thank you! Since I'm new to the TS stuff, your solution looks a bit gobbledy-gookish to me at first, so I'll definitely look at it carefully to make sure that I truly grok it before putting it in. But this looks very promising!

And we are already using TS 3.8.3 - so ? and ?? operators shouldn't be a problem.

Cheers!

Collapse
 
ecyrbe profile image
ecyrbe • Edited

Yes, the hardest part is this one :

{ [K in keyof T]: T extends Record<K, T[K]> ? never : K }
Enter fullscreen mode Exit fullscreen mode

Witch means, return me an object type that has the same properties as Props, but with property types equal to the property name if the underlying property is not required .
then :

{ [K in keyof T]: T extends Record<K, T[K]> ? never : K }[keyof T]
Enter fullscreen mode Exit fullscreen mode

that means return me a union of all the optional properties names of Props.

Then the idea is to have setDefaults(), not compile if you try to pass default parameters not declared in Props, or if you forgot to add defaults that where declared optional in Props.

This is where you will thank typescript for having your back everytime you forgot to handle a default parameter, because typescript will catch it.

Thread Thread
 
bytebodger profile image
Adam Nathaniel Davis

Excellent stuff. And thank you(!) for the extended explanation. I've been coding for 20+ years and I've done plenty of generics in languages like C#. But when you're in a "JavaScript mindset", it can still take a little bit to get your head back in that mindspace.

All though I'm generally a big fan of generics, when you haven't been working with them for awhile, code like that above can look like the first time that you dove into regular expressions.

Cheers!