es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Inferencia de instrucciones literales y estrechamiento de tipos en Typescript.

Tengo el siguiente código:

export type EntityType = "foo" | "bar";
export interface Foo {
  id: `foo-${string}`;
}
export interface Bar {
  id: `bar-${string}`;
}

export type Ent<t extends="" entitytype=""> = T extends "foo" ? Foo : Bar;
export const resolve = <t extends="" entitytype="">(id: `${T}-${string}`): Ent<t> => {
  if (id.startsWith("foo-")) {
    return { id: "foo-a" };
  }
  if (id.startsWith("bar-")) {
    return { id: "bar-a" };
  }
  throw new Error(`Unsupported entity type ${id}`);
};

Las declaraciones de retorno están lanzando un error que dice: `Type ‘{ id: “foo-a”; }’ no se puede asignar a tipo ‘Ent‘.

Esto ocurre porque TS no puede inferir que .startsWith("foo-") coincide realmente con la interfaz Foo, lo cual es comprensible.

¿Existe alguna forma de indicar al compilador para que pueda deducir y reducir correctamente el tipo de retorno esperado? En este momento, solo funciona si lo convierto a cualquier tipo:

ts
if (id.startsWith("foo-")) {
return { id: "foo-a" } as any;
}

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma de dar una pista al compilador para que pueda inferir y reducir el tipo de retorno esperado. Una posible solución es utilizar una aserción de tipo para afirmar que el valor de retorno coincide con el tipo de retorno esperado para cada caso. Por ejemplo:

    export const resolve = <t extends="" entitytype="">(id: `${T}-${string}`): Ent<t> => {
      if (id.startsWith("foo-")) {
        return <><t>>{ id: `foo-a` };
      }
      if (id.startsWith("bar-")) {
        return <><t>>{ id: `bar-a` };
      }
      throw new Error(`Tipo de entidad no compatible ${id}`);
    };
    

    Al utilizar la aserción de tipo <><t>>, le indicamos al compilador que trate el valor de retorno como tipo Ent<t>, aunque puede que no pueda inferirlo solo con el código. Esto nos permite reducir el tipo de retorno esperado para cada caso, lo que elimina la necesidad de convertirlo a any.

Comments are closed.