Home > Blockchain >  Convert Array<string> to Record<Enum> in TypeScript
Convert Array<string> to Record<Enum> in TypeScript

Time:05-12

Having

export enum PropertyCode {
  _D = '_D',
  ABCO = 'ABCO',
  ACC = 'ACC',
  // ... etc

I have a function that should return a Record<PropertyCode, any>

public getProperties(): Record<PropertyCode, any> {

    let propertyArray: [PropertyCode, any][] = this.propertyControls?.map(
        (x) => [x.value.propertyCode, x.value.value]) ?? [];

    return propertyArray // [string, any][] ==>??? Record<PropertyCode, any> 
}

I have a compile error :

Type '[PropertyCode, any][]' is missing the following properties from type 'Record<PropertyCode, any>': _D, ABCO, ACC, ACCO, and 255 more.

How should I convert the array to Record, without explicitly filling all 255 enum codes?

CodePudding user response:

You should try it with .reduce:

return propertyArray.reduce((acc, curr) => {
  acc[curr[0]] = curr[1]
  return acc
}, {} as Record<PropertyCode, any>) 

Playground

CodePudding user response:

As @captain-yossarian correctly notes, you can't use map, since it doesn't return a Record. You'll need to do it yourself, and also decide what to do in case of a duplicate code. Below example shows it, both without and with using array.reduce (I personally don't find that it adds much to readability, YMMV).

Playground link

enum PropertyCode {
    _D = '_D',
    ABCO = 'ABCO',
    ACC = 'ACC',
    // ... etc
}

interface PropertyControl {
    value: {
        propertyCode: PropertyCode;
        value: string;
    }
}

const propertyControls: PropertyControl[] = [
    { value: { propertyCode: PropertyCode._D, value: 'b' } },
    // ...etc
];

function getProperties(): Record<PropertyCode, any> {
    const acc = {} as Record<PropertyCode, any>;
    for (const curr of propertyControls) {
        if (acc[curr.value.propertyCode]) {
            throw `duplicate propertyCode ${curr.value.propertyCode}`;
        }
        acc[curr.value.propertyCode] = curr.value.value;
    }

    return acc;
}

function getPropertiesUsingReduce(): Record<PropertyCode, any> {
    return propertyControls.reduce((acc, curr) => {
        if (acc[curr.value.propertyCode]) {
            throw `duplicate propertyCode ${curr.value.propertyCode}`;
        }
        acc[curr.value.propertyCode] = curr.value.value;
        return acc;
    }, {} as Record<PropertyCode, any>);
}

console.log(getProperties());
console.log(getPropertiesUsingReduce());
  • Related