1

I'd like to use an array to iterate through interface properties, however it's throwing a ts compile error on the forEach function:

interface A {
  foo: string
  bar: string
  baz: string
}

function fn(obj: A) {
  ;["foo", "bar"].forEach( (prop: keyof A) => {
    obj[prop] // do stuff
  })
}

The error:

Argument of type '(prop: keyof A) => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'. Types of parameters 'prop' and 'value' are incompatible. Type 'string' is not assignable to type 'keyof A'

Something like this would work, but it feels redundant:

function fn(obj: A) {
  const ar: (keyof A)[] = ["foo", "bar"]
  ar.forEach( (prop: keyof A) => {
    obj[prop] // do stuff
  })
}

1 Answer 1

2

TypeScript infers the type of ["foo", "bar"] to be string[], which can't be assigned to type keyof A because it could contain strings that aren't in that type. If you tell TypeScript that your array is of type (keyof A)[] then it works. For example:

interface A {
  foo: string
  bar: string
  baz: string
}

function fn(obj: A) {
  ;(["foo", "bar"] as (keyof A)[]).forEach( (prop) => {
    obj[prop] // do stuff
  })
}

TypeScript playground

That example uses a type assertion, though, which it's preferrable to avoid when possible as it bypasses TypeScript's type checking. You can avoid that by using something like this instead, which will refuse to compile if you attempt to put a string in your array that isn't one of A's property names:

interface A {
  foo: string
  bar: string
  baz: string
}

function fn(obj: A) {
  let values: (keyof A)[] = ['foo', 'bar'];
  values.forEach( (prop) => {
    obj[prop] // do stuff
  })
}

TypeScript playground

Sign up to request clarification or add additional context in comments.

1 Comment

This is perfect thank you! Didn't realize I could infer the parameter type like that.

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.