He entendido que algo así como:
type GenericExample<T> = T extends (infer U) ? U : 'bar';
es igual a:
type GenericExample<T> = T extends T ? T : 'bar';
Pero cuando las cosas se vuelven más elaboradas, TypeScript se queja:
type Types = 'text' | 'date' | 'articles' | 'params';
type MyExperiment<Type extends Types> = { t : Type };
type MyExperimentsUnion = Types extends (infer U) ? MyExperiment<U> : never;
// Type 'U' does not satisfy the constraint 'Types'.
// Type 'U' is not assignable to type '"params"'.
Entonces, me gustaría preguntar por qué esto está mal: en este caso particular, la distribución sobre la unión debería tener lugar, por lo que el U
tipo inferido debería ser text
, date
y así sucesivamente. Entonces, ¿qué significa T extends (infer U)
realmente y cuándo sería apropiado usarlo?
fuente
infer
palabra clave, pero hice esta extraña pregunta porque descubrí queT extends (infer U)
es válida en un tipo condicional, me sorprendió eso y comencé a investigar.U
. ¿Qué deberíaMyExperiment<U>
ser? Quiero decir,U
debe ser "subclase" deTypes
, pero typecript no puede determinar qué es exactamente,U
ya que no está pasando ningún tipo (no es tipo genérico), y no veo por qué debería ser predeterminadoTypes
. Supongo que esa es una de las razones por las que obtienes el error, aunque estoy de acuerdo en que podría ser más descriptivo, pero parece que van con el estado de ánimo de que los desarrolladores deben saber queinfer
no se debe usar de esa manera.Probablemente no valga más de dos centavos pero:
Se me ocurren algunas razones por las que
MyExperimentsUnionConstraint
funciona peroMyExperimentsUnion
no funciona, pero no tengo el conocimiento profundo del idioma para expresarlas de modo que tenga sentido.Para dar una explicación con el ejemplo:
MyExperimentsUnion
, fromTypes extends U
,U
podría inferirse comoTypes | 'bla'
y luegoMyExperiment<Type | 'bla'>
no funciona.MyExperimentsUnionConstraint
,U
solo se puede inferir como algo que funciona conMyExperiment
fuente