NoInfer<Type>
Blokuje wnioskowanie parametru typu z danego miejsca, żeby typ ustalały inne argumenty.
Przykład
#function createSelect<T extends string>(options: T[], initial: NoInfer<T>) {
return { options, selected: initial }
}
const difficulty = createSelect(['easy', 'medium', 'hard'], 'medium')
// T = "easy" | "medium" | "hard", wywnioskowane tylko z options
console.log(difficulty.selected)
createSelect(['easy', 'medium', 'hard'], 'expert')
// Błąd: Argument of type '"expert"' is not assignable to parameter of type '"easy" | "medium" | "hard"'.medium
Definicja i zastosowanie
#NoInfer<Type> oznacza pozycję, z której kompilator nie powinien wnioskować parametru typu. Sam typ się nie zmienia: NoInfer<string> to nadal string. Zmienia się tylko to, skąd TypeScript bierze informacje, gdy ustala T przy wywołaniu funkcji generycznej.
Typowa sytuacja to funkcja z listą dozwolonych wartości i wartością początkową. Jeśli oba parametry mają typ T, kompilator wywnioskuje T z obu argumentów, więc literówka w wartości początkowej po cichu poszerzy unię, zamiast zgłosić błąd. Z NoInfer<T> przy wartości początkowej typ pochodzi wyłącznie z listy.
Typ jest dostępny od TypeScriptu 5.4. W starszych wersjach ten sam efekt daje drugi parametr typu z ograniczeniem, np. <T extends string, D extends T>.
Składnia
#function nazwa<T>(zrodlo: T[], inny: NoInfer<T>) { … }Parametry typu
#Type
dowolny typ
Typ, który pozostaje bez zmian, ale nie bierze udziału we wnioskowaniu.
Więcej przykładów
#function createSelectLoose<T extends string>(options: T[], initial: T) {
return { options, selected: initial }
}
const loose = createSelectLoose(['easy', 'medium', 'hard'], 'expert')
// T = "easy" | "medium" | "hard" | "expert", brak błędu
console.log(loose.selected)expert
function createSelectOld<T extends string, D extends T>(options: T[], initial: D) {
return { options, selected: initial }
}
createSelectOld(['easy', 'medium', 'hard'], 'expert')
// Błąd: Argument of type '"expert"' is not assignable to parameter of type '"easy" | "medium" | "hard"'.Dobre praktyki
#- Stosuj
NoInferwtedy, gdy jeden argument ma ustalać typ, a pozostałe mają być tylko z nim porównywane, np. wartość początkowa z listą opcji. - W większości funkcji generycznych
NoInfernie jest potrzebny. Dodawaj go dopiero wtedy, gdy wnioskowanie z któregoś argumentu daje zbyt szeroki typ.
Powiązane hasła
#- Generyki <T>Typy i funkcje z parametrem typu, działające dla wielu typów bez utraty precyzji.
- Ograniczenia generyków (extends)Wymaganie, żeby parametr typu spełniał określony kształt.
- Wnioskowanie typówAutomatyczne ustalanie typów przez kompilator bez pisania adnotacji.
- Typy literałoweTypy dopuszczające tylko konkretne wartości, np. "easy" | "hard".
- Domyślne parametry typuWartość, jaką przyjmuje parametr typu, gdy nie zostanie podany ani wywnioskowany.
Widzisz błąd albo brakuje przykładu? Napisz do nas.