1

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?

1
  • Map callback returns an array of tuples whereas you want to return a hashmap object. Consider using Array.prototype.reduce. Please provide reproducible example Commented May 11, 2022 at 11:55

2 Answers 2

1

You should try it with .reduce:

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

Playground

Sign up to request clarification or add additional context in comments.

1 Comment

what about const properties = Object.assign({}, ...values.map((x) => ({ [x.propertyCode]: x.value })));
1

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 keys. Below example shows it, both without and with using array.reduce (I personally don't find it adds 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());

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.