NoInfer<Type>

Blokuje wnioskowanie parametru typu z danego miejsca, żeby typ ustalały inne argumenty.

Na tej stronie

Przykład

#
TypeScript
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"'.
Wynik
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

#
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

#
Bez NoInfer literówka przechodzi
TypeScript
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)
Wynik
expert
Sposób sprzed TypeScriptu 5.4
TypeScript
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 NoInfer wtedy, 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 NoInfer nie jest potrzebny. Dodawaj go dopiero wtedy, gdy wnioskowanie z któregoś argumentu daje zbyt szeroki typ.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.