Home > OS >  How to create typescript interface for array of objects with array as values
How to create typescript interface for array of objects with array as values

Time:06-14

I have input data in this form:

const input = {
    postcode: ['0000']
    submitted: ['yes']
}

const output = {
    postcode: '0000'
    submitted: 'yes'
}

How to create interface for input data?

I tried:

interface inputData {
    postcode: string[]
    submitted: string[]
}

interface outputData {
    postcode: string
    submitted: string
}

But I get error while applying it:

const extract = (input: inputData[]): outputData => {
  for (const key in input) {
    if (Object.hasOwnProperty.call(input, key)) {
      input[key] = input[key][0]; // Error here
    }
  }
  const output: any = input;
  return output;
}

Error: Element implicitly has an 'any' type because expression of type '0' can't be used to index type 'inputData'. Property '0' does not exist on type 'inputData'.

CodePudding user response:

Here is a working version

function hasOwnProperty<X extends {}, Y extends PropertyKey>
  (obj: X, prop: Y): obj is X & Record<Y, unknown> {
  return obj.hasOwnProperty(prop)
}

interface inputData {
    postcode: string[];
    submitted: string[];
}
type outputData = inputData;

const extract = (input: inputData): outputData => {
    for (const key in input) {
        if (hasOwnProperty(input, key)) {
            const value = input[key];

            if (value instanceof Array) {
                input[key] = value[0];
            }
        }
    }
    const output: any = input;
    return output;
}

CodePudding user response:

From the information you've provided the type of inputData is Record<string,string[]>` Record is a utility type (Link)

    postcode: ['0000'],
    submitted: ['yes']
}

type inputDataT = Record<string,string[]>

interface inputData {
    postcode: string[]
    submitted: string[]
}

const extract = (input: inputDataT) => {
  const output: any = input;
  for (const key in input) {
    if (Object.hasOwnProperty.call(input, key)) {
      output[key] = input[key][0];
    }
  }

  return output;
}
console.log(extract(inputData))

Also if you're sure that there will only ever be one string in the property value array you can make it stronger as follows:

type inputDataT = Record<string,[string]>
const inputData:inputDataT = {
    postcode: ['0000'],
    submitted: ['yes']
}

Playground

CodePudding user response:

You can define an interface with an indexer:

interface EnumServiceGetOrderBy {
    [index: number]: { id: number; label: string; key: any };
}
  • Related