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;
};