javascript - Definición de una función usando los genéricos

CorePress2024-01-24  9

Teniendo un código tan simple:

interface ServerData {
  foo: string
  bar: number
}

const oo = {
  foo: "abc",
  bar: 887
}

function foo<ServerData>(x: ServerData): number { return x.foo }

Recibo el error en el última línea:

Property 'foo' does not exist on type 'ServerData'

Es extraño ya que la interfaz ServerData ya está definida anteriormente. ¿Qué está pasando?



------------------------------------

Es porque el tipo genérico ServerData definido en la función podría no tener la propiedad foo (el genérico y la interfaz no son lo mismo, debes decirle esto al compilador).

En ninguna parte del código le dices al compilador que el genérico tiene esta propiedad. En su caso, podría deshacerse del genérico por completo de esta manera (también tendría que convertir foo en un Número ya que la función returna un número):

function foo(x: ServerData): number { return Number(x.foo) }

o podría decirle al compilador que el tipo genérico en la función implementa la interfaz ServerData de esta manera:

function foo<T extends ServerData>(x: T): number { return Number(x.foo) }

El problema básico aquí es que no le estás diciendo al compilador cuál es realmente este tipo, por lo que no sabe que el parámetro tiene esta propiedad. Si desea pasar un genérico y decirle al compilador que la propiedad foo existe, también puede hacer esto:

function foo<T extends {foo: string}>(x: T): number { return Number(x.foo) }



------------------------------------

Un complemento a la respuesta de @WilsonPena.

En su declaración de la función foo ServerData es una variable de tipo local; no se refiere a la global tipo/interfaz ServerData. Su declaración es en realidad equivalente a

function foo<T>(x: T): number { return x.foo }

Aquí queda más claro que no se sabe si el objeto x tiene un campo foo.

Lo que probablemente quieras es

function foo(x: ServerData): number { return x.foo }

Ahora el motor de tipos sabe que hay un campo foo en x. Sin embargo, obtendrás otro error ya que el campo foo en ServerData es una cadena, pero has declarado que la función foo devuelve un número.

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare