Use Partial<INodeMailerResponseUpper>
for the reduce
type parameter. This will mean acc
has that type and will allow you to assign properties to it. However, you need to cast the result to INodeMailerResponseUpper
because TypeScript doesn’t know that the final result will contain all the required properties.
You could do it like this, which uses a fair bit of type assertions:
const formattedResponse = Objectkeys(response)
.reduce<Partial<INodeMailerResponseUpper>>((acc, key) => {
(acc[upperFirst(key) as keyof INodeMailerResponseUpper] as unknown) =
response[key as keyof INodeMailerResponseLower];
return acc;
}, {}) as INodeMailerResponseUpper;
Or you could also improve the type of lodash’s upperFirst
(using TypeScript 4.1):
declare module 'lodash' {
interface LoDashStatic {
upperFirst<S extends string = ''>(string?: S): Capitalize<S>;
}
}
const formattedResponse = (Object.keys(response) as (keyof INodeMailerResponseLower)[])
.reduce<Partial<INodeMailerResponseUpper>>((acc, key) => {
// Without the as unknown, TypeScript would complain that
// string | number | string[] is not assignable to undefined
(acc[upperFirst(key)] as unknown) = response[key];
return acc;
}, {}) as INodeMailerResponseUpper;
Unfortunately, there isn’t a way to completely avoid type assertions.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…