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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.