Home > Net >  Get explicit key names for autocompletion in Typescript
Get explicit key names for autocompletion in Typescript

Time:08-29

What I want to do is given an object with a certain type, pass it through a function, completely remove either mobile or web parts depending on which one I tell it to remove and then also remove the key of the one I want to keep and shift its contents up below the mobile/web parent. This image will demonstrate this.enter image description here Ive simplified the example to reduce the code, so if it seems pointless that may be why.

So then when I have the object it should look like this

const newObj: NewTypeCreated = {
  key1: {
    width: 150,
    height: 400,
  },
  key2: {
    width: 100,
  },
};

I already have this working with this code

const customComponentsStyle = (
  comps: ResponsiveCustomComponentsStyle,
  mobileOrWeb: 'mobile' | 'web',
) =>
  Object.keys(comps).reduce((newObj, currentKey) => {
    const { width, height, maxHeight } = customComponents[currentKey][mobileOrWeb]!;
    const newObject = {
      ...(width && { width }),
      ...(height && { height }),
      ...(maxHeight && { maxHeight }),
    };

    return {
      ...newObj,
      [currentKey]: newObject,
    };
  }, {});

const x = customComponentsStyle(customComponents, 'mobile');
console.log(x);

//Output
{ key1: { width: 150, height: 400 }, key2: { width: 100 } }

The issue is there is no autocompletion on x it has no idea what is on it.

console.log(x.key1.width);

ts error
Property 'key1' does not exist on type '{}'.ts(2339)

Can anyone point me in the right direction here? I just want to be able to do x and have proper auto completion based on the new objects type.

CodePudding user response:

You could explicitly tell Typescript that customComponentsStyle returns NewTypeCreated type of data:

const customComponentsStyle = (
  comps: ResponsiveCustomComponentsStyle,
  mobileOrWeb: 'mobile' | 'web',
): NewTypeCreated => {
  ...
}

This will tell Typescript that customComponentsStyle returns an object with string properties, where each property is an object with optional numbers in width and height.

CodePudding user response:

You could add these types below

type KeyType = {
  width?: number
  height?: number
}

type ReturnType = {
  key1?: KeyType
  key2?: KeyType
}

and change the customComponentsStyle function like this code screenshot

const customComponentsStyle = (
  comps: ResponsiveCustomComponentsStyle,
  mobileOrWeb: 'mobile' | 'web',
): ReturnType =>
  Object.keys(comps).reduce((newObj, currentKey) => {
    const { width, height, maxHeight } = customComponents[currentKey][mobileOrWeb]!;
    const newObject = {
      ...(width && { width }),
      ...(height && { height }),
      ...(maxHeight && { maxHeight }),
    };

    return {
      ...newObj,
      [currentKey]: newObject,
    };
  }, {} as ReturnType);

  • Related