Be Careful With Return Types In TypeScript

Theo - t3․gg
6 Feb 202312:07

Summary

TLDREl guion discute la controversia sobre el uso de tipos de retorno en TypeScript, argumentando que muchas opiniones comunes son incorrectas. Se presenta un ejemplo donde la inferencia de tipos sin especificar explícitamente los tipos de retorno resulta en una representación más precisa y verdadera del resultado de una función. El guion destaca cómo los tipos de retorno explícitos pueden 'mentir', ocultando o alterando la verdad sobre los datos que una función realmente devuelve. Se enfatiza la importancia de la verdad en la programación y cómo la inferencia siempre refleja la verdad, aunque sea más amplia, mientras que los tipos de retorno pueden ser engañosos y peligrosos si no se usan con precaución.

Takeaways

  • 🔍 Evitar los tipos de retorno cuando sea posible puede ser beneficioso.
  • 🤔 Los tipos de retorno estrictos pueden llevar a resultados inexactos y engañosos.
  • 💡 Usar 'as const' en TypeScript puede proporcionar resultados más precisos.
  • 🚫 Los tipos de retorno pueden mentir y causar errores difíciles de detectar.
  • 📊 Diagrama: La inferencia de tipos a menudo da la verdad, incluso si es más vaga.
  • ⚠️ Ejemplo de 'getUser': La inferencia de tipos incluye 'password', mientras que un tipo de retorno lo omite erróneamente.
  • 🔄 Sobrecarga y tipos de retorno: Pueden dar resultados incorrectos si no se manejan adecuadamente.
  • 📝 La inferencia de tipos es más segura y cercana a la verdad en la mayoría de los casos.
  • 🌐 El consenso general entre los expertos es preferir la inferencia de tipos.
  • 💬 Comentarios de expertos: La mayoría prefiere la inferencia de tipos por su precisión y seguridad.

Q & A

  • ¿Por qué es importante discutir cómo se deben escribir las funciones en TypeScript?

    -Es importante porque hay muchas opiniones erróneas sobre cómo se deben escribir las funciones, y entenderlo mejor puede mejorar la calidad y la seguridad del código.

  • ¿Qué es un 'contrived inferred example' y por qué se utiliza en el script?

    -Es un ejemplo artificial creado para ilustrar un concepto específico, en este caso, para demostrar cómo TypeScript infiere tipos sin especificarlos explícitamente.

  • ¿Por qué se recomienda evitar los tipos de retorno en ciertos casos según el script?

    -Se recomienda evitar los tipos de retorno cuando se pueden inferir correctamente por TypeScript, ya que los tipos inferidos pueden ser más precisos y revelan la 'verdad' sobre lo que realmente se está devolviendo.

  • ¿Qué es 'as const' y cómo afecta la inferencia de tipos en TypeScript?

    -'as const' es una forma de hacer que TypeScript trate los valores como constantes en lugar de como tipos más genéricos, lo que puede resultar en un tipo más estricto y preciso.

  • ¿Cómo se puede usar la inferencia de 'as const' para mejorar la precisión del tipo de retorno de una función?

    -Al usar 'as const', TypeScript garantiza que el tipo devuelto sea exactamente el resultado de la función, sin ambigüedades ni generalizaciones innecesarias.

  • ¿Por qué pueden ser los tipos de retorno considerados como 'mentirosos' según el script?

    -Los tipos de retorno pueden ser considerados 'mentirosos' porque a veces no reflejan con precisión lo que realmente se está devolviendo, lo que puede llevar a errores o malentendidos en el código.

  • ¿Qué es un 'diagrama de tipos' y cómo se utiliza en el script para ilustrar un punto?

    -Un 'diagrama de tipos' es una representación gráfica que muestra las relaciones entre diferentes tipos posibles y la 'verdad' del tipo real. Se utiliza para ilustrar cómo las diferentes soluciones se relacionan con la 'verdad' y cuánto se alejan de ella.

  • ¿Qué ejemplo se utiliza para mostrar cómo los tipos de retorno pueden 'mentir' en el caso de un objeto 'User'?

    -Se utiliza un ejemplo donde una función 'getUser' devuelve un objeto 'User' con un campo 'password' que no debería estar presente, pero que se incluye en el tipo de retorno, lo cual es incorrecto y puede causar confusiones.

  • ¿Qué es 'getUser override' y cómo puede ser problemático según el script?

    -'getUser override' es una forma de especificar un tipo de retorno específico para una función sobrescrita. Puede ser problemático porque puede inducir a errores al no reflejar correctamente los valores que se están devolviendo.

  • ¿Por qué se sugiere ser cauteloso con los tipos de retorno y cómo se puede mejorar la inferencia de tipos?

    -Se sugiere ser cauteloso con los tipos de retorno porque pueden contener información incorrecta o incompleta. Para mejorar la inferencia de tipos, se puede confiar en la inferencia de TypeScript por defecto y utilizar 'as const' cuando sea necesario para una precisión más estricta.

Outlines

00:00

🤔 Evitar tipos de retorno en TypeScript

El primer párrafo discute la polémica sobre cómo se deben escribir las funciones en TypeScript, y cómo muchos de los prejuicios son incorrectos. Se argumenta que, en algunos casos, deberíamos evitar los tipos de retorno. Se da un ejemplo de una función que devuelve un objeto con un estado y un valor, y se muestra cómo la inferencia de tipos sin especificar explícitamente el tipo de retorno puede resultar en un tipo más preciso. Además, se compara con el uso de 'as const' para obtener una inferencia más estricta y se concluye que, en algunos casos, los tipos de retorno pueden ser menos precisos que la inferencia por sí sola.

05:01

😕 Las limitaciones de los tipos de retorno

En el segundo párrafo, se profundiza en los problemas de los tipos de retorno, como la facilidad con la que pueden 'mentir' o no reflejar la verdad sobre los datos que se están manipulando. Se presenta un ejemplo donde el tipo de retorno está mal definido y cómo esto puede llevar a errores en la comprensión de los datos que se están devolviendo. Se argumenta que los tipos de retorno pueden ser menos precisos y cómo la inferencia pura puede ser una alternativa más fiable. Se utiliza un diagrama para ilustrar cómo la inferencia y los tipos de retorno se relacionan con la 'verdad' subyacente de los datos involucrados.

10:02

🚫 Contraargumentos y consideraciones finales

El tercer párrafo ofrece una reflexión final sobre el uso de tipos de retorno en TypeScript. Se mencionan ejemplos de cómo los tipos de retorno pueden ser problemáticos y cómo la inferencia puede ser una solución más segura y precisa. Se argumenta que, en la mayoría de los casos, la inferencia es suficiente y que deberíamos ser cautelosos al introducir tipos de retorno explícitos. Se sugiere que, si se necesita un tipo de retorno específico, debería haber una documentación clara para advertir sobre la facilidad de 'mentir' con ellos. Se concluye con la preferencia de varios desarrolladores por la inferencia en lugar de los tipos de retorno explícitos.

Mindmap

Keywords

💡Tipos de retorno

Los tipos de retorno son una característica de TypeScript que permite especificar el tipo de dato que una función devolverá. En el video, se cuestiona la necesidad de usar tipos de retorno en ciertas situaciones, ya que pueden llevar a una representación menos precisa del resultado real de una función, como se muestra en el ejemplo de la tupla con 'status', 'valor' y 'error'.

💡Inferencia de tipos

La inferencia de tipos es el proceso por el cual TypeScript deduce el tipo de una variable o valor basándose en su uso en el código. El video argumenta que la inferencia puede ser más precisa y menos propensa a errores que los tipos de retorno explícitos, ya que estos pueden 'mentir' al no reflejar correctamente los datos que una función devuelve.

💡Const

En TypeScript, `as const` se utiliza para instruir al compilador a tratar una expresión como un valor constante, lo que puede resultar en un tipo más estricto y específico. El video menciona `as const` como una forma de obtener tipos más precisos que los tipos de retorno, al garantizar que el resultado sea el 'verdadero' resultado de una función.

💡Diagnóstico de errores

El diagnóstico de errores se refiere a la capacidad de TypeScript para informar al programador sobre problemas potenciales en el código, como tipos inesperados o incompatibilidades. En el contexto del video, se destaca cómo los tipos de retorno pueden generar errores al no coincidir con los datos reales que una función devuelve.

💡Ejemplos contrived

Un ejemplo 'contrived' es un ejemplo artificial o forzado creado para ilustrar un punto específico. En el video, se utilizan ejemplos contrived para demostrar cómo los tipos de retorno pueden ser menos precisos que la inferencia de tipos o `as const`, y cómo pueden llevar a conclusiones erróneas sobre los resultados de una función.

💡Diagramas

El video utiliza diagramas para ilustrar visualmente la relación entre los tipos de retorno, la inferencia de tipos y la 'verdad' en términos de los datos que se esperan de una función. Los diagramas ayudan a entender cómo los diferentes métodos de tipado se comparan con la precisión y la representación real de los datos.

💡Mentiras en el sistema de tipos

El video argumenta que los tipos de retorno pueden 'mentir' al no reflejar con precisión los datos que una función realmente devuelve. Esto puede ocurrir cuando se especifican tipos de retorno que no coinciden con los resultados reales, lo que puede llevar a errores o a una comprensión incorrecta del código.

💡Sobreescritura de tipos

La sobreescritura de tipos se refiere a la capacidad de TypeScript de permitir que los tipos de retorno explícitos anulen o cambien los tipos inferidos por el compilador. El video muestra cómo esto puede ser problemático, ya que puede llevar a que los tipos de retorno no reflejen la realidad de los datos devueltos por una función.

💡Ejemplos de código

El video presenta varios ejemplos de código para ilustrar los puntos discutidos, como la diferencia entre los tipos de retorno y la inferencia de tipos, y cómo estos pueden afectar la precisión y la seguridad del tipado en TypeScript. Estos ejemplos son cruciales para entender las limitaciones y ventajas de cada enfoque.

💡Evitar tipos de retorno

El mensaje principal del video es que, en muchos casos, es mejor evitar los tipos de retorno y confiar en la inferencia de tipos o `as const` para obtener una representación más precisa y menos propensa a errores de los resultados de una función. El video argumenta que los tipos de retorno, aunque pueden parecer más claros, pueden introducir 'mentiras' en el sistema de tipos.

Highlights

存在许多关于在TypeScript中如何编写函数的观点,但许多观点是错误的。

讨论了避免在TypeScript中使用返回类型的情况。

示例展示了在函数中不使用返回类型,TypeScript会如何推断类型。

使用as const可以更严格地推断类型,因为它将值视为常量。

使用as const可以保证获得准确的结果类型。

添加返回类型可能会覆盖更精确的类型推断结果。

通过图示解释了类型定义与实际返回值之间的关系。

类型定义的目标是尽可能接近实际返回值的真实类型。

返回类型可能包含谎言,因为它们可能不完全反映函数的实际返回值。

使用类型推断可以避免在类型定义中撒谎。

示例展示了如何通过返回类型覆盖实际返回值,导致类型定义不准确。

讨论了类型守卫和类型覆盖的问题,以及它们如何可能导致错误的类型定义。

使用类型覆盖可能会隐藏函数实际返回的额外属性。

讨论了typescript中的类型守卫和类型覆盖的潜在风险。

提出了一个类型覆盖的例子,该例子在直播中看起来有效,但后来被发现是完全错误的。

强调了在TypeScript中使用类型覆盖时需要非常小心,以避免类型定义与实际返回值不一致。

建议在大多数情况下使用类型推断,除非有特定的性能考虑或需要明确指定类型。

强调了在TypeScript中使用类型推断的重要性,以及它如何帮助保持代码的真实性。

多位TypeScript专家分享了他们对于使用类型推断还是显式返回类型的看法。

讨论了在TypeScript中使用类型推断的普遍性和其优势。

呼吁在TypeScript中默认使用隐式返回类型,除非有特殊情况。

视频结尾提出了结束关于TypeScript类型定义的争论的希望。

Transcripts

play00:00

turns out there's a lot of opinions on

play00:01

how to type your functions in typescript

play00:03

and it turns out a lot of those opinions

play00:04

are wrong this convo has been fun but

play00:06

it's time to end it let's talk about why

play00:08

you should avoid return types when

play00:09

you're able to in this example we have a

play00:11

result type the result is the thing we

play00:13

get back from this function a result has

play00:15

a status which is either OK or error and

play00:17

it has a value or an error if the status

play00:19

is error and this contrived inferred

play00:21

example we're not passing a return type

play00:23

which means this type isn't being used

play00:24

and the result is that the type that we

play00:27

get back has a value that is either

play00:29

string or undefined even if we check and

play00:32

confirm status is okay what we're

play00:34

getting back here is this weird Tuple of

play00:36

status during values during error

play00:38

undefined or status string error error

play00:40

value undefined and that's not a great

play00:42

representation of the types going on

play00:44

here if we give this a strict type by

play00:46

putting a type definition at the end of

play00:48

the function def like I have here then

play00:50

we'll see with this contrived example we

play00:52

now know confidently that value is

play00:54

string after confirming the status is

play00:56

okay this seems like a pretty obvious

play00:58

compelling example of when you would

play00:59

would want to use return types right

play01:03

told you we could do better because I

play01:05

think we can

play01:07

this next example is using as const

play01:11

because in this example there is a set

play01:13

of values that are and aren't valid and

play01:16

as const basically tells typescript

play01:18

don't treat the things in here as

play01:19

strings treat them as constants you'll

play01:21

notice we get something even more strict

play01:23

that's interesting we get back yay why

play01:26

are we getting back yay here well the

play01:28

only two things this can actually return

play01:30

are status OK value yay or status error

play01:34

error error because of that the true

play01:37

type of this function is status okay

play01:40

value yay or status error error new

play01:43

error and when you use as const with

play01:45

inference without the type definition

play01:47

you're guaranteed the correct result

play01:49

like the exact correct result the actual

play01:52

truth of what's being done and being

play01:53

returned funny enough if you add back

play01:56

the return type on here it actually

play01:58

overrides the truth with a more vague

play02:01

result and you'll see here in space is

play02:04

far enough

play02:06

now the result now is that value is

play02:07

string even though we know value is yay

play02:10

because the as const gets overridden by

play02:13

the thing you put here you all know

play02:14

anything about me you know I love

play02:16

diagrams so obviously I was going to

play02:17

throw this in a diagram I have a key

play02:19

here with the four things that will be

play02:20

visible in any given piece I drew a

play02:22

circle which is all the potential types

play02:24

we could reasonably think result might

play02:28

be it's our goal as developers to narrow

play02:31

that type definition down to its very

play02:33

core of the truth

play02:34

so in this diagram I have the potential

play02:36

as a black circle on the outside and I

play02:38

have the truth as this little green

play02:39

circle on the inside we're trying to

play02:41

figure out how these different solutions

play02:43

relate to the truth if we take the same

play02:45

code the result the values type is EA

play02:48

the raw inference does not give us yay

play02:50

it doesn't even give us string it gives

play02:52

us string or undefined which means the

play02:54

types that it could potentially be are

play02:56

large return types narrow it slightly as

play02:59

we see here because return type knows it

play03:02

has to be a string so in this case the

play03:04

type is more narrowed it's closer to the

play03:06

truth and then we have in the center

play03:08

here cons d a because if you as const

play03:12

these with constant inference

play03:14

the result is the exact truth the exact

play03:17

thing that we're getting back here

play03:18

guaranteed thankfully in this example

play03:21

all of the different options contain the

play03:24

truth which means we're bickering over

play03:27

the scope of what exists outside of the

play03:30

truth here and I understand I can

play03:32

totally see why people would not want

play03:33

this area to exist and if they could

play03:35

avoid it would choose to but what if I

play03:37

told you it wasn't that simple

play03:39

what if I told you

play03:40

return types can lie I think lies are

play03:44

the root of all evil and type systems I

play03:46

prefer vagueness to not telling the

play03:49

truth and with inference you can't lie

play03:51

with return types it's trivial to lie

play03:54

and it's even pretty easy to

play03:56

accidentally let lies slip through code

play03:57

review the first example I have here

play03:59

comes credit Julius one of the lead

play04:01

maintainers and creators of create T3

play04:03

app Julius made an example that comes

play04:06

close to my heart because I've made

play04:07

mistakes like this before where we have

play04:09

a user type that has a username and

play04:10

email and notably it doesn't have a

play04:12

password because this is meant to be the

play04:13

user that we return to a user when they

play04:16

make a request on our application

play04:18

however if we have a function get user

play04:21

that returns things that it shouldn't

play04:23

like in this case a password this type

play04:25

is not representative of what this

play04:27

function returns and if we don't give

play04:29

this function a type and we call it and

play04:31

we get the response we see the inferred

play04:33

responses or we see that the type that

play04:35

we get back is correct it's username

play04:37

email and password it knows that we have

play04:39

the password here because we returned it

play04:41

so obviously that's going to appear in

play04:43

the typed result

play04:44

sadly it's very easy for strict type

play04:47

returns to override that result so in

play04:50

this case

play04:51

and get user strict we have a return

play04:53

type of user which only has a username

play04:55

and an email so even though we are

play04:57

returning something with a password that

play04:59

we would want to see in our types

play05:00

definition it's not there anymore by

play05:03

putting this type here we have

play05:04

overridden the type of this or we've

play05:08

overridden the type such that password

play05:10

magically vanishes in typescript land

play05:12

even though it's still there that's a

play05:15

lie this is an incorrect type definition

play05:17

if we take a look at the diagram for

play05:19

this it should highlight where the lies

play05:21

are happening so we again have our black

play05:24

circle and the truth within it the type

play05:26

of user.password when we call user is

play05:29

very different depending on which of

play05:30

these Solutions we use to type it the

play05:32

truth of what user.password is here is

play05:34

pass because that is what we're getting

play05:36

back when we call user.password if we

play05:38

use raw inference we're going to get

play05:39

back a string which is fine it lets us

play05:42

know that we have a string there when we

play05:43

don't intend to and that the return or

play05:45

the response of get user has a password

play05:47

in it so it's still correct it just has

play05:50

more vague around what the type is

play05:52

because it's a generic string not the

play05:54

specific string totally fine

play05:56

the return type will actually give you

play05:58

an error here when you try to touch

play06:00

check or interface with user.password it

play06:03

will error because you've told

play06:04

typescript no that doesn't exist even

play06:06

though it does the return type is now

play06:09

giving you an error on data that

play06:11

actually exists and you have all of the

play06:13

things to know that that data exists

play06:15

if you ask constant you're going to get

play06:17

passed because that's what the value is

play06:18

here and it's now been made into a

play06:20

constant but the harsh reality here is

play06:23

that all of these are the truth except

play06:26

for return types

play06:27

because return types here

play06:29

contain some of the truth but are also

play06:31

missing some of it

play06:33

they're lying a lie is when you don't

play06:35

include the truth in your response and

play06:37

that is what I see here when you use

play06:39

return types it becomes much easier to

play06:42

lie and that's a huge concern to me

play06:45

we can negotiate and argue all day

play06:48

around the merits of making your type

play06:49

definition closer to the truth but we

play06:52

also have to acknowledge that return

play06:54

types allow you to move the type further

play06:56

away from the truth and outside of the

play06:59

scope of Truth very scary for my final

play07:01

example I want to show the code that

play07:02

primogen gave an example with on stream

play07:04

yesterday because although it looks good

play07:07

on the stream we later figured out it's

play07:09

entirely broken and super risky so much

play07:11

so that Prime even replied earlier today

play07:13

saying I showed overloading lying which

play07:15

it does and typescript should get rid of

play07:17

that behavior immediately well

play07:19

typescript behaves how typescript

play07:20

behaves and right now return types

play07:22

enable typescript to lie a lot in this

play07:24

example we have a type user which has a

play07:27

role either user or admin we call this

play07:29

get user function I need to get user

play07:30

overrides because this is the one we're

play07:31

overriding it you call it an ID we call

play07:33

it with a role we then return that role

play07:37

ideally we'd probably return other

play07:38

things here like permissions and stuff

play07:39

but the example is meant to be simple

play07:40

where roles user we get back roll user

play07:42

role as admin we get back roll admin the

play07:45

override here is basically telling

play07:47

typescript oh by the way if you pass

play07:49

this you're guaranteed this subset of

play07:51

the type because get user overrides

play07:54

always returns a user and both of these

play07:57

are valid users so we've effectively

play07:59

said here is if the input matches this

play08:01

type then the response has to match this

play08:03

type

play08:04

I don't know how closely you've been

play08:05

looking but that's not the truth here

play08:07

because if roll is user we're not

play08:10

returning role user we're actually

play08:11

returning role admin if you didn't

play08:13

notice that then you would have failed

play08:14

this encode review because guess what

play08:16

the types are lying here if we look at

play08:19

user override the response will get user

play08:21

override with user it thinks the type of

play08:23

is role user but it isn't we have just

play08:26

used the override here to lie to

play08:28

typescript because we told typescript no

play08:31

you don't know better about our types we

play08:32

know better about our types but we don't

play08:34

here we were wrong and a code reviews

play08:36

the only way you're not going to ship

play08:38

this code

play08:39

however

play08:40

if you just let inference do its thing

play08:42

you're going to get a more vague type

play08:44

sure it's not ideal I understand but in

play08:48

this case this more vague type of string

play08:51

or null is the truth and I personally

play08:54

believe truthy code is more valuable

play08:57

than slightly more narrow type

play08:59

definitions if we take a look on the

play09:01

diagram here you'll see why this one's

play09:03

so scary the truth is roll admin and

play09:05

sadly even with the consts we can't

play09:08

narrow it down to here without the

play09:11

possibility of lying the raw inference

play09:13

would be roll string or null just pretty

play09:15

accurate totally fine to operate within

play09:18

the override return type so if you're

play09:20

using overrides for the return type on

play09:21

this it's now going to be roll colon

play09:23

user which is a lie if we ask cost

play09:25

everything we're gonna get back roll

play09:26

user or roll admin or null because it

play09:29

knows strictly what these are that

play09:31

doesn't necessarily know the mapping of

play09:32

when you pass a specific role which

play09:34

thing comes back that all said God

play09:36

override return types just don't exist

play09:39

within the truth at all in this case

play09:41

you'd have to actually modify the code

play09:42

to bring these back to the truth and

play09:45

then all future code modifications have

play09:47

to be cognizant of the fact that this

play09:49

type may not overlap with the truth and

play09:51

you as a developer have to be very very

play09:53

proactive to make sure that happens

play09:56

or way easier just don't give it a type

play09:59

the vast majority of the time if you

play10:02

don't type the response of the function

play10:03

the type you get back is good enough to

play10:06

work with and on the rare occasions it

play10:07

isn't you can as constant move on you

play10:09

really want this function of a specific

play10:10

narrowed down type you better put a

play10:12

massive comment on it letting future

play10:13

developers know that it's easy to lie if

play10:16

they aren't careful once we get into any

play10:18

this becomes way more common but even in

play10:21

these simple use cases where all of the

play10:22

inputs and outputs are strictly typed

play10:24

return types often lie to you

play10:27

so be careful don't use return types if

play10:29

you don't have to I don't think they're

play10:30

100 evil I think they're closer to like

play10:32

20 I just wish we would acknowledge that

play10:35

20 evil and be very very careful about

play10:37

how we introduce evil into our code

play10:39

bases inference always tells the truth

play10:42

even if the truth is more vague return

play10:44

types can lie to you and you should be

play10:46

careful when you use them as good as I

play10:48

am a typescript I relied on much smarter

play10:49

people to help build this stance and

play10:51

also find all of these examples so I'm

play10:53

going to let all of them let you know

play10:54

what they think

play10:55

hey I'm Malta and I prefer inferred

play10:58

return types I'm trash and I generally

play11:00

prefer inferring my return types hey I'm

play11:03

Ben and for strong intuitive safe typing

play11:06

I try to default to inference in

play11:08

typescript hi my name is Josh Goldberg

play11:10

and I generally prefer inferring return

play11:13

types hey I'm Dax and I prefer inferring

play11:17

return types hi I'm Maple Leaf and I

play11:20

prefer inferring return types hey I'm

play11:22

Alex and I almost always in fire types

play11:26

hi there I'm Tanner lensley and a vast

play11:28

majority of the time I use inferred

play11:30

return types

play11:31

hi I'm Ken C Dons and although I don't

play11:34

like hard and fast rules most of the

play11:36

time I infer my return types hi I'm Napo

play11:38

cook I think you should be using

play11:40

inferred return types by default except

play11:42

when you have a function with multiple

play11:44

branches except in library code and

play11:46

except when you have really Niche weird

play11:49

performance concerns with the typescript

play11:51

compiler where a return type solves it

play11:53

but that's it by default use implicit

play11:56

returns hopefully we can end this

play11:58

conversation once and for all if you

play11:59

want to know more about ways people use

play12:01

typescript wrong I'm going to pin a

play12:02

video right there so take a watch of

play12:04

that one should be good

play12:06

peace nerds

Rate This

5.0 / 5 (0 votes)

Related Tags
TypeScriptProgramaciónTipadoInferenciaDesarrolloOptimizaciónEjemplosErroresMétodosCódigo
Do you need a summary in English?