After getting the error unions can't be used in index signatures, use a mapped object type instead
I am now attempting to convert a string literal union (key names of an interface) to a mapped object, as explained here. https://github.com/microsoft/TypeScript/issues/24220#issuecomment-390063153
But it still isn't working:
const returnObject: {
[index : mappedObjectOfConfigDataKeys] : Partial<ConfigData>
} = {...accumulator};
// error TS1023: An index signature parameter type must be either 'string' or 'number'.
// 51 [index : // mappedObjectOfConfigDataKeys] : // Partial<ConfigData>
// ~~~~~
if (currentStepInstance.hasSaveableData && currentStepInstance.configDataKey) {
returnObject[currentStepInstance.configDataKey] = validatedUserInput;
}
// error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
// No index signature with a parameter of type 'string' was found on type '{}'.
// 55 returnObject[currentStepInstance.configDataKey] = validatedUserInput;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To prove the prior issue:
const returnObject: {
[index : stringLiteralUnion] : Partial<ConfigData>
} = {...accumulator};
// (parameter) index: stringLiteralUnion
// An index signature parameter type cannot be a union type. Consider using a mapped object type instead.ts(1337)
Anyone know how to fix this? These last two attempts have me in circles. The compiler seems to want the mapped object to pass a constrained set of strings; I don't know how to give it that in an acceptable way.
export default interface ConfigData {
languageCode : string
, numberOfRepeats : number
, projectId : string
}
/**** Index Signature handling for the above interface ****/
export type stringLiteralUnion = "languageCode" | "numberOfRepeats" | "projectId";
export type mappedObjectOfConfigDataKeys = {[key in stringLiteralUnion]: string};
// also tried typing it as `any` as shown in the linked post
// same error occured
Typescript Playground
Update 1
Attempted:
const returnObject: Record<keyof ConfigData, Partial<ConfigData>> = {...accumulator};
Error message:
const returnObject: Record<"languageCode" | "numberOfRepeats" | "projectId", Partial<ConfigData>>
Type '{ languageCode?: string | undefined; numberOfRepeats?: number | undefined; projectId?: string | undefined; }' is not assignable to type 'Record<"languageCode" | "numberOfRepeats" | "projectId", Partial<ConfigData>>'.
Types of property 'languageCode' are incompatible.
Type 'string | undefined' is not assignable to type 'Partial<ConfigData>'.
Type 'undefined' is not assignable to type 'Partial<ConfigData>'.ts(2322)
Update 2
Attempted:
const returnObject: Record<"languageCode" | "numberOfRepeats" | "projectId", Partial<ConfigData>> = {...accumulator};
Error:
const returnObject: Record<"languageCode" | "numberOfRepeats" | "projectId", Partial<ConfigData>>
Type '{ languageCode?: string | undefined; numberOfRepeats?: number | undefined; projectId?: string | undefined; }' is not assignable to type 'Record<"languageCode" | "numberOfRepeats" | "projectId", Partial<ConfigData>>'.
Types of property 'languageCode' are incompatible.
Type 'string | undefined' is not assignable to type 'Partial<ConfigData>'.
Type 'undefined' is not assignable to type 'Partial<ConfigData>'.ts(2322)