Reputation: 301
I have a predefined array of strings STRINGS_ARR
.
I am trying to create an object STRINGS_OBJ
using the strings in that array.
Each key of the object should be dynamically generated by removing underscore character from the input string, and the value should be the input string itself.
For example: if input string is 'Some_Test_Name', then the key should be 'SomeTestName`, and the value of the key should be 'Some_Test_Name'.
I am able to write the code to fulfill the requirement and generate such an object with required key/value pairs.
But, I am not able to write type/define the structure of the object, such that TypeScript will be able to infer the value correctly for the given key.
This is what I have so far, and TypeScript is not able to infer the type of the Value
, and rightly so, because the Key
I am trying to extract out of InputString
has been modified and is no longer matching.
type InputStringMap = {
[Key in KeyName<InputString>]: Extract<InputString, Key>
};
type Key = keyof InputStringMap;
type Value = InputStringMap[Key];
// ^? type Value = never
What should be the correct type/definition for such an object?
type InputString = 'Test_String_1' | 'Test_String_2';
const STRINGS_ARR: InputString[] = ['Test_String_1', 'Test_String_2'];
type KeyName<S extends string> = string extends S ? 'Error' : S extends `${infer A}_${infer B}` ? KeyName<`${A}${B}`> : S;
type InputStringMap = {
[Key in KeyName<InputString>]: Extract<InputString, Key>
};
type Key = keyof InputStringMap;
type Value = InputStringMap[Key];
// ^? type Value = never
const keyValuePairs = STRINGS_ARR.map<[Key, Value]>((str) => [str.replace(/_/g, '') as Key, str as Value]);
const STRINGS_OBJ = Object.fromEntries(keyValuePairs) as InputStringMap;
Upvotes: 2
Views: 28
Reputation: 328302
The easiest way to do this is with key remapping via as
:
type InputStringMap = {
[K in InputString as KeyName<K>]: K
};
which produces
/* type InputStringMap = {
TestString1: "Test_String_1";
TestString2: "Test_String_2";
} */
as desired.
Upvotes: 2