object with some specific properties typescript

Viewed 67

I have a function that accepts some data and function add some properties and return that parameter object.

this is how I am declaring it

async setContext(@Body() data: { [key: string]: any }): Promise<{
        additionalData: { id: string, [key: string]: any },
        context: Context,
        [key: string]: any
    }> {
        data.additionalData.id = this._getId(data.additionalData);
        data.context = this._getContext();
        return data;
}

but this is showing

Type '{ [key: string]: any; }' is missing the following properties from type '{ [key: string]: any; additionalData: { [key: string]: any; id: string; }; context: Context; }': additionalData, contextts(2739)

so I tried

async setContext(@Body() data: { additionalData?: any, context?: Context, [key: string]: any }): Promise<{
        additionalData: { id: string, [key: string]: any },
        context: Context,
        [key: string]: any
    }> {
        if (!data.additionalData) {
            data.additionalData = {};
        }
        data.additionalData.id = this._getConversationId(data.additionalData);
        data.context = this._getContext();
        return data;
}

but now this is showing

Type '{ [key: string]: any; additionalData?: any; context?: Context; }' is not assignable to type '{ [key: string]: any; additionalData: { [key: string]: any; id: string; }; context: Context; }'.
  Property 'additionalData' is optional in type '{ [key: string]: any; additionalData?: any; context?: Context; }' but required in type '{ [key: string]: any; additionalData: { [key: string]: any; id: string; }; context: Context; }'.ts(2322)

should not this work as I am declaring data as

data: { [key: string]: any }

to have any unknown properties?

2 Answers

I would define the returned type of the function depending on the type of parameters of the function.


Playground


To use it in your case, just replace 'foo' and 'bar' by your functions.


type Context = string;

type DataIn = { 
  additionalData?: unknown;
  context?: Context;
  [key: string]: unknown;
};

type DataOut = Omit<Required<DataIn>, 'additionalData'> & {
  additionalData: { 
    id: string;
    [key: string]: unknown;
  };
};

async function setContext(data: DataIn): Promise<DataOut> {
  return {
    ...data,

    additionalData: {
      ...(data.additionalData as object),

      id: 'foo',
    },

    context: 'bar',
  };
}

(async() => {
  const myData = await setContext({
    animal: 'dog',
  });

  console.log(myData);
})();

You need to return a promise which matches with the function signature:

async function setContext(@Body() data: { [key: string]: any }): Promise<{
        additionalData: { id: string, [key: string]: any },
        context: Context,
        [key: string]: any
    }> {
        let map:{ additionalData: { id: string, [key: string]: any }, context: Context, [key: string]: any };
        data.additionalData.id = this._getId(data.additionalData);
        data.context = this._getContext();
        return new Promise((resolve, reject) => { resolve(map) });
}

The type of input parameter data is incompatible with the signature which is causing a compilation error

Playground link here

In short, either your input parameter type needs to be changed or the returning object should be populated locally

Related