[Typescript] Represent Generics at the Lowest Level

 

 

There are two solutions to this challenge, both with different ways of representing the generic.

Solution 1:

The first option is using TConfig which extends rawConfig and includes featureFlagshomePage, and any:

export const getHomePageFeatureFlags = <
  TConfig extends {
    rawConfig: {
      featureFlags: {
        homePage: any;
      };
    };
  }
>(
  ...

Hovering over getHomePageFeatureFlags in the tests will show the the entire object is being captured in the generic slot when using TConfig as the type argument.

This means that we can index into TConfig to find the type that the flag should be:

export const getHomePageFeatureFlags = < TConfig extends { rawConfig: { featureFlags: { homePage: any; }; }; } >( config: TConfig, override: ( flags: TConfig["rawConfig"]["featureFlags"]["homePage"] ) => TConfig["rawConfig"]["featureFlags"]["homePage"] ) => { return override(config.rawConfig.featureFlags.homePage); };

As you can see, this approach of capturing the generic on a higher level can be quite messy and captures a lot of unnecessary code.

 

Solution 2:

Using HomePageFlags directly as the generic makes for a more elegant solution since it is the argument for the override function.

We can now drill down to config.rawConfig.featureFlags.homePage inside of the argument:

export const getHomePageFeatureFlags = <HomePageFlags>( config: { rawConfig: { featureFlags: { homePage: HomePageFlags; }; }; }, override: (flags: HomePageFlags) => HomePageFlags ) => { return override(config.rawConfig.featureFlags.homePage); };

With this solution, hovering over getHomePageFeatureFlags in the test will only show us the stuff we care about inside of homePage instead of the entire object.

// hovering over getHomePageFeatureFlags 
const getHomePageFeatureFlags: <{ showBanner: boolean; showLogOut: boolean; }>...

Being able to access only the specific properties we want instead of drilling down twice makes the code much more readable.

A general rule of thumb for working with generics is to always represent them with a low-level type. As seen in the second solution, it's more efficient to drill down to find the specific type argument.

posted @ 2023-01-14 22:20  Zhentiw  阅读(15)  评论(0编辑  收藏  举报