Home > Back-end >  How to use function argument as a key in object interface
How to use function argument as a key in object interface

Time:10-21

I have a function that manipulates an array of unknown objects in which I have a nested_key as parameter. When I'm trying to use it for accessing a key in the object, typescript of course complains because it doesn't know the key is present in the object. Is there any way to define an interface that would take that parameter and add it into the typescript interface as key?

Simplified function:

interface NestedItem {
  [key: string]: unknown
}

function manipulate(arr: NestedItem[], nested_key: string) {
  console.log(arr[0][nested_key].length)
}

So what I need exactly is to somehow use the value of nested_key like e.g. this:

interface NestedItem {
  [key: nested_value]: unknown[]
}

I also tried to first check whether the prop is the correct type but that seems not to help when checking with this function:

const is_array = (value: unknown): value is unknown[] => Array.isArray(value)

CodePudding user response:

instead of unknown use any so your interface should be

interface NestedItem {
  [key: string]: any
}

and use safe navigation operator ? while fetching the length so it doesn't break your code in case the key is not in the arr

function manipulate(arr: NestedItem[], nested_key: string) {
  console.log(arr[0][nested_key]?.length)
}

CodePudding user response:

A possible extension to your function could be, ensuring that nested_key is a key of NestedItem, using the keyof keyword.

interface NestedItem {
  [key: string]: unknown
}

function manipulate(arr: NestedItem[], nested_key: keyof NestedItem) {
  arr[0][nested_key] = 'new value'
}

Additionally, immutability is important to consider.

If your Array (arr) cannot be mutated, it may be wise to spread arr first to a temporary object, like so:

function manipulate(arr: NestedItem[], nested_key: keyof NestedItem):NestedItem[] {
  let resultObject = [...arr];
  resultObject[0][nested_key] = 'new value';
  return resultObject;
}

OR:

function manipulate(arr: NestedItem[], nested_key: keyof NestedItem):NestedItem[] {
  let resultObject = [...arr];
  resultObject[0] = {
    ...resultObject[0],
    [nested_key]: 'new value'
  };
  return resultObject;
}

NB: I am a fan of produce by Immer which can help handle the whole idea of immutability

  • Related