Reputation: 385
I have an object containing a list of supported languages. I'd like to find the user's browser contains one of the languages:
const userLanguage = browserLanguages.find(language => !!supported[language]);
However, I'm getting the following error: Element implicitly has an 'any' type because type 'LanguageName' has no index signature.
LanguageName
is a type I've created for my supported
object:
type LanguageName = {
[language in SupportedLanguages]: string;
};
And supportedLanguages
is a type containing all languages supported by our app:
type SupportedLanguages = 'en' | 'es';
Upvotes: 1
Views: 59
Reputation: 327819
I think you'll get the best results by explicitly invoking the overload of Array.find()
which treats the callback as a user-defined type guard. Note that you have to do this via manual annotation; the compiler does not currently infer type guards from function return values.
There are multiple ways to do this; here's one:
// make an explicit type guard for SupportedLanguages
function supportedLanguageGuard<T extends keyof any>(
x: T
): x is T & SupportedLanguages {
return !!(supported as any)[x];
}
// use it
const userLanguage: SupportedLanguages | undefined = browserLanguages.find(
supportedLanguageGuard
); // okay
I went this way because it should work whether or not you narrow browserLanguages
to keep track of the literals inside it
const browserLanguages = ["fr", "es"] as const; // TS3.4+
Okay, hope that helps. Good luck!
Upvotes: 2