Issue
I want to do the best practice possible, so first I check if the propertyKey
is property of objectParent
. Here's my playground code
const objectParent = {
product: 'this is product',
shipping: 'this is shipping',
};
const firstOne = false;
const displayOrder = firstOne
? (['a', 'b'] as const)
: (['a', 'b', 'c', 'product', 'shipping'] as const);
for (const propertyKey of displayOrder) {
if (propertyKey in objectParent) {
console.log(objectParent[propertyKey]);
}
}
I expect that since I already added a typeguard using if (propertyKey in objectParent)
, typescript should allow me using propertyKey
as the index. I know you can bypass this using propertyKey as keyof typeof objectParent
but I feel like that's not a solution since kinda lazy writing
Solution
The confusion here arises from the fact Type Script is a compiled language, and your check is dynamic. In normal JS,
if(propertyKey in objectParent)
would suffice, since everything is dynamic, and during runtime the indexing is guaranteed to be what you want. Of course, in that case you could index with anything and just get undefined
, which is part of the thing TS is trying to work against.
Thus, a compile time hint for propertyKey
needs to be provided, to let the compiler know that the index type is valid for indexing. This as simple as
propertyKey as keyof typeof objectParent
which is essentially telling the compiler to trust you, and you will ensure in runtime the values are valid index values - of course, now it's up to you to not make mistakes (such as forgetting the if
guard).
This goes somewhat against the spirit of being type safe though, and it seems this is a perfect case for the object itself carrying the display order with it. If multiple different objects need to be supported, it suffices they provide a display order interface which a function can use to display them all.
Answered By - kabanus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.