1

While using Object.entries() it returns correct values types, but keys are as string[] which is not correct. I want to force TS to be aware of my keys. I tried to use as const on object but this did nothing.

Is it possible to assert type in this case?

const demo = {
  a: 'TEST',
  b: 222,
} as const

Object.entries(demo)
  .forEach(([key, value]) => { // key is string and not "a" | "b"
    console.log([key, value])
  })

// reproduce same types as above
Object.entries(demo)
  .forEach(([key, value]: [string, typeof demo[keyof typeof demo]]) => {
    console.log([key, value])
  })

// now trying to change string to actual keys, error :(
Object.entries(demo)
  .forEach(([key, value]: [keyof typeof demo, typeof demo[keyof typeof demo]]) => {
    console.log([key, value])
  })

// so instead trying to force somehow type assertion
Object.entries(demo)
  .forEach(([key as keyof typeof demo, value]) => { // how to make assertion???
    console.log([key, value])
  })

Playground

1 Answer 1

1

keys are as string[] which is not correct

It was designed to be that way, because objects can be extended. You may know that it wasn't extended, but the type system can't enforce that. An example:

interface Person {
  name: string;
  age: number;
}

interface Employee extends Person {
  department: string;
}

const someFunction (person: Person) {
  Object.entries([key, value] => {
    // `key` will sometimes be 'name' or 'age', but those aren't its only
    // values. In this example, it will be 'department', and it could be
    // absolutely any string, hence the type string.
  });
}

const alice: Person = { name: 'alice', age: 30 }
const bob: Employee = { name: 'bob', age: 30, department: 'legal' }

someFunction(alice); // legal of course
someFunction(bob); // Also legal

If you'd like to assert that you know there are no extra properties, the following is probably the easiest way:

Object.entries(demo)
  .forEach(([k, value]) => {
    const key = k as keyof typeof demo
    console.log([key, value])
  })
Sign up to request clarification or add additional context in comments.

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.