1

I have a library function which returns an array of objects:

function someLibraryFunc(): object[]

I need to access a property of type string inside the returned objects, but the compiler is complaining:

function myFunc(prop: string): string[] {
   someLibraryFunc()
      .map(obj => obj[prop] as string) // <-- compiler error
}

/*
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.   
No index signature with a parameter of type 'string' was found on type '{}'.
*/

I've tried to add index signature like so:

function myFunc(prop: string): string[] {
   someLibraryFunc()
      .map((obj: { [key: string]: string }) => obj[prop]) // <-- compiler error
}

/* 
TS2345: Argument of type '(obj: { [key: string]: string; }) => string' is not assignable to parameter of type '(value: object, index: number, array: object[]) => string'.   
Types of parameters 'obj' and 'value' are incompatible. Type 'object' is not assignable to type '{ [key: string]: string; }'.       
Index signature is missing in type '{}'.
*/

I've tried also the following:

function myFunc(prop: string): string[] {
   someLibraryFunc()
      .map((obj: { [key: string]: string }, index: number, array: object[]) => obj[prop]) // <-- compiler error
}

/* 
TS2345: Argument of type '(obj: { [key: string]: string; }) => string' is not assignable to parameter of type '(value: object, index: number, array: object[]) => string'.   
Types of parameters 'obj' and 'value' are incompatible. Type 'object' is not assignable to type '{ [key: string]: string; }'.       
Index signature is missing in type '{}'.
*/

What is the proper way to add index signature to the arguments in the map function?

1
  • What do you expect myFunc("somePropertyNotPresentInReturnedObjects") to output? The typing of myFunc() says that needs to produce a string[], but I expect you're going to get an undefined[] at runtime. Do you have some desired constraint on prop that you haven't mentioned? Commented Jan 14, 2020 at 1:20

2 Answers 2

2

You might want to explicitly assert that the prop is really the key of object:

declare function someLibraryFunc(): object[]

function myFunc(prop: string): string[] {
    return someLibraryFunc()
        .map(obj => obj[prop as keyof typeof obj] as string)
}

Playground

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

Comments

2

The typing of these functions depend on the Array<T> interface, so you can cast the type returned by someLibraryFunc() instead:

(someLibraryFunc() as { [key: string]: string }[])
       .map(obj => obj[prop])

If possible you'd want more specific types defined for your function in the first place though.

1 Comment

I don't think you need that intervening as unknown in there.

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.