0

I have object with interface and I would like to dynamically access values by property key.

const tmpUser: IUser = {
    username: "test",
    namespace: "test",
    password: "test"
}

Object.keys(tmpUser).forEach(property=>{
    // Error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'IUser'.
    console.log(tmpUser[property]);
})

// works
console.log(tmpUser["username"]);

// works
const someKey = "username";
console.log(tmpUser[someKey]);

also tmpUser.hasOwnProperty(property) doesn't help neither.

2
  • instead of forEach(property => , try forEach((property: keyof IUser) => Commented Jun 19, 2020 at 13:01
  • 2
    @MikeS. that won't work because Object.keys(tmpUser) is already string[], so forEach expects a callback whose first parameter is string: Type 'string' is not assignable to type '"username" | "namespace" | "password"'. Commented Jun 19, 2020 at 13:04

3 Answers 3

2
+50

Because Object.keys does not allow use to pass a generic type, its return type is string[], if we want to have type [keyof IUser] we can cast it

const keys: [keyof IUser] = Object.keys(tmpUser) as [keyof IUser]
keys.forEach((property)=>{
    console.log(tmpUser[property]);
})

BUT: It's is unnecessary. If you want to get key and value of that key you can simply use

Object.entries(tmpUser).forEach(([key,value])=>{
   
})
Sign up to request clarification or add additional context in comments.

Comments

2

You can specify that the IUser keys will be of type string (or if you want e. g. string | number):

interface IUser extends Record<string, any> {
    username: string
    namespace: string
    password: string
}

Comments

0

Throwing another solution here, especially since I'm assuming you'll have some kind of a process function that takes in an object and does something with it:


const process = <O extends { [key: string]: any }>(object: O) => {
    Object
        .keys(object)
        .forEach(prop => {
            // No longer complains
            console.log(object[prop]);
        });
}

process(tmpUser);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.