Reputation: 326
TypeScript's inference is very good. However, this example does not work as expected and needs a //@ts-ignore
.
for (const p in obj) {
if (p !== 'staticCounter' && p !== 'staticProperty') {
//@ts-ignore
delete obj[p];
}
}
Without ignore, I get the error
const p: string Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Obj'. No index signature with a parameter of type 'string' was found on type 'Obj'.ts(7053)
and obj
is of type
interface Obj {
a?: string;
o?: string;
b?: string;
...
}
While the idea is easy to grasp, I think it will not be easy to implement into TypeScript. A "Can be a key for obj" type is not what the type system supports.
But can this be improved on my side? I don't like //@ts-ignore
s.
I am not looking for other ways to achieve the same thing. I chose this way, because it proved faster than creating a new object and assigning it the two new properties.
Upvotes: 2
Views: 942
Reputation: 10345
This is a well-known limitation of TypeScript. The most recent issue asking to narrow string
type to keyof
of the object being iterated is presently open and awaits more feedback. Should you want to see it implemented, please go there, put a "like" on the issue and optionally provide a comment explaining your use case.
In the meantime an alternative to declaring the variable outside the for...in
loop is to type cast:
interface Obj {
a?: string;
o?: string;
b?: string;
}
const obj : Obj = {
a: "John",
b: "Mary"
};
for(const p in obj) {
delete obj[<keyof Obj>p];
}
Upvotes: 1
Reputation: 74096
You can put a type annotation like this:
let p: keyof Obj
for (p in obj) {
.
.
.
Upvotes: 1