У меня есть объект, содержащий список поддерживаемых языков. Я хотел бы найти, что браузер пользователя содержит один из языков:
const userLanguage = browserLanguages.find(language => !!supported[language]);
Однако я получаю следующую ошибку: Element implicitly has an 'any' type because type 'LanguageName' has no index signature.
LanguageName
— это тип, который я создал для своего объекта supported
:
type LanguageName = {
[language in SupportedLanguages]: string;
};
А supportedLanguages
— это тип, содержащий все языки, поддерживаемые нашим приложением:
type SupportedLanguages = 'en' | 'es';
Я думаю, вы получите наилучшие результаты, явно вызвав перегрузка Array.find()
, который обрабатывает обратный вызов как защита пользовательского типа. Обратите внимание, что вы должны сделать это с помощью ручной аннотации; компилятор в настоящее время не вывести защиту типа из возвращаемых функцией значений.
Есть несколько способов сделать это; вот один:
// 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
Я пошел этим путем, потому что он должен работать независимо от того, сужаете ли вы browserLanguages
, чтобы отслеживать литералы внутри него.
const browserLanguages = ["fr", "es"] as const; // TS3.4+
Хорошо, надеюсь, это поможет. Удачи!