Home > database >  Typescript reduce return wrong Type and also forbid to assert it
Typescript reduce return wrong Type and also forbid to assert it

Time:04-30

Faced very strange ts behaviour.

type Labels = Record<string, boolean | undefined>

type LabelGroups = Record<string, Labels>

export function reduceLabelGroups(labelGroups: LabelGroups) {
    const labels = Object.entries(labelGroups).reduce((valueMap, [, value]) => ({...valueMap, ...value}), {});

    return labels;
}

It should return Labels Type after reduce - but it returns just {} If you try to assert Labels like a

(...{} as Labels);

it throws error "Unnecessary cast: Array#reduce accepts a type parameter for the default value." How can I return type without any "as unknown as Labels" after return?

CodePudding user response:

It's just as the error says - .reduce accepts a type parameter, so use it.

export function reduceLabelGroups(labelGroups: LabelGroups) {
    return Object.entries(labelGroups).reduce<Labels>((valueMap, [, value]) => ({...valueMap, ...value}), {});
}

Might be more appropriate to use Object.values, since you're not using the keys.

export function reduceLabelGroups(labelGroups: LabelGroups) {
    return Object.values(labelGroups).reduce<Labels>((valueMap, value) => ({...valueMap, ...value}), {});
}

Or perhaps avoid .reduce entirely, it's not so appropriate here

export function reduceLabelGroups(labelGroups: LabelGroups) {
    const valueMap: Labels = {};
    for (const value of Object.values(labelGroups)) {
        Object.assign(valueMap, value);
    }
    return valueMap;
};

You can do shorter, but it requires a type assertion.

export function reduceLabelGroups(labelGroups: LabelGroups) {
    return Object.assign({}, ...Object.values(labelGroups)) as Labels;
};
  • Related