0

I am trying to access an object using index notation in typescript. But I cannot find a way that keeps my types (without using any).

In typescript I get the following error (strict mode):

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ givenName: string; familyName: string; email: string; active: boolean; }'.

No index signature with a parameter of type 'string' was found on type '{ givenName: string; familyName: string; email: string; active: boolean; }'.

// Example document
interface user {
  givenName: string
  familyName: string
  email: string
  active: boolean
}

const user:user = {
  givenName: 'Max',
  familyName: 'Maier',
  email: '[email protected]',
  active: true,
}

// To be used like this
const match = ['givenName', 'familyName', 'email'].find(e => 
    !!user[e] && user[e].toLowerCase().includes('searchQuery')
)

there are no errors when using a static string.

!!user['givenName'] && user['givenName'].toLowerCase().includes('searchQuery')

Defining an indexer seems to always throw me into the problem of loosing type safety. E.g.

[index: string]: string | boolean | undefined

will give an error with the .toLowerCase() . I could fix it using any but that is not what I want.

In my opinion the best solution would be to make typescript understand that e is an existing index with something like this:

['givenName', 'familyName', 'email'].find((e:'givenName'| 'familyName'| 'email' ) =>

But I failed getting the error:

Type 'string' is not assignable to type '"givenName" | "familyName" | "email"'

I'm able to hack it using any but I can't figure out type safe way to solve this.

1 Answer 1

1

Do it this way

const match = (['givenName', 'familyName', 'email'] as const).find(e => 
    !!user[e] && user[e].toLowerCase().includes('searchQuery')
)

Then the array is typed as an array of union of literals, not just as a string[] and the e is properly typed as a union of literals correspondingly.

References:

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.