Issue
There is converting an array of strings into object:
const myFields = ['field1', 'field2'];
const myObject = myFields.reduce((obj, fld) => ({ ...obj, [fld]: `val of ${fld}` }), {});
In this case type of myObject
will be {}
and access to myObject.field1
will be displayed with error.
How to make actual type from array of strings?
Like:
type MyObject = {
field1: string,
field2: string
};
Solution
How to make actual type from array of strings?
You can't, with the array you've shown. The array's values would have to be known at compile-time, like this:
const myFields = ['field1', 'field2'] as const;
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^
If they aren't, then you can't definitely type the object, since you need to know what those values are to define the type, and the type only exists at compile-time.
If you can't do that, you're pretty much stuck with Record<string, string>
.
If you can add the as const
so the array values are known at compile-time, then you can define the type of the object as Record<typeof myFields[number], string>
, which picks out the values of the array (tuple) as property names and uses them in a record where their values will be strings. The code would look like this:
const myFields = ['field1', 'field2'] as const;
const myObject = myFields.reduce(
(obj, fld) => ({ ...obj, [fld]: `val of ${fld}` }),
{} as Record<typeof myFields[number], string>
);
(There's a small lie there we get away with [initially, {}
isn't a valid Record<typeof myFields[number], string>
], but it's no longer a lie once the reduce
is complete.)
After the above, this would be valid code:
console.log(myObject.field1);
console.log(myObject.field2);
But again, that only works when the array is a compile-time constant.
Side note: You'll notice I added ()
around the expression body of your arrow function, since otherwise the leading {
means you're writing a full function body, not an expression function body.
Answered By - T.J. Crowder
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.