泛型 typescript
by Nadeesha Cabral
通过Nadeesha Cabral
如何把你的头围绕Typescript泛型 (How to wrap your head around Typescript generics)
Sometime back when the “Flow vs. Typescript” debate was raging, I had to pick a side. And I picked Typescript. Fortunately, that was one of the better decisions I made. When I had to make that decision, ultimately what convinced me was Typescript’s support for call-time generics.
有时在“流与打字稿”辩论激烈时,我不得不选择一方。 我选择了Typescript。 幸运的是,这是我做出的更好的决定之一。 当我不得不做出决定时,最终使我信服的是Typescript对呼叫时间泛型的支持 。
Today, let me try to walk you through what generics accomplish and how it helps us write safer, cleaner and more maintainable code.
今天,让我尝试引导您完成泛型的工作,以及它如何帮助我们编写更安全,更清洁和更可维护的代码。
示例1:声明一个简单类型 (Example 1: Asserting a simple type)
Let’s say we need a function that takes any value and puts that into an object. A naive implementation of this in Typescript would look and run like:
假设我们需要一个接受任何值并将其放入对象的函数。 在Typescript中对此的幼稚实现看起来和运行如下:
So much for type-safety.
对于类型安全来说,就这么多。
It’s true that myValue
can be of any type. But what we need to tell the controller is that the output of the function, although it cannot be foreseen as the developer writing the code, can be “inferred” by the type of the input type. In other words, we can have a “generic definition” of what the output is.
确实myValue
可以是任何类型。 但是我们需要告诉控制器的是,尽管开发人员无法编写代码,但可以通过输入类型来“推断”函数的输出。 换句话说,我们可以对输出内容有一个“通用定义”。
Generic implementation of the above function would be something like this:
上述功能的通用实现如下所示:
What we’re simply saying is that myValue
can have a type of T
. It can be “any type” but not any
type. In other words, it has a type we care about.
我们只是在说myValue
可以具有T
的类型。 它可以是“任何类型”,但不能是any
类型。 换句话说,它具有我们关心的类型。
If you try to write the earlier execution in Typescript, you won’t be able to run it, as the compiler gives a helpful warning:
如果尝试在Typescript中编写较早的执行,则将无法运行它,因为编译器会给出有用的警告:
示例2:使用泛型编写idx (Example 2: Writing idx with Generics)
idx
is a “Library for accessing arbitrarily nested, possibly nullable properties on a JavaScript object”. It’s especially useful when you work with complex Javascript objects like REST API responses that may have nullable fields.
idx
是“用于访问JavaScript对象上任意嵌套的,可能为空的属性的库”。 当您使用复杂的Javascript对象(如REST API响应,可能具有可为空的字段)时,此功能特别有用。
If you don’t mind me oversimplifying this a bit, it accomplishes this by basically try
ing the function given as the second parameter with props
. If it fails, it catch
es and returns an undefined
value safely, without throwing.
如果您不介意过分简化,它会通过基本try
使用props
作为第二个参数给出的函数来实现。 如果失败,它会catch
es并安全地返回undefined
值,而不会抛出异常。
Again, a naive implementation of this would be:
同样,此方法的简单实施是:
But, if we’re a bit clever with generics, we can get Typescript to help us with this.
但是,如果我们对泛型有点聪明,可以使用Typescript来帮助我们。
We’ve introduced two generics here.
我们在这里介绍了两个泛型。
T
for the input type, and we “hint” that it’s an object by saying T extends {}
. U
is for the output type. And with these, we can express that the selector
function is something that takes T
and returns U
of undefined.
T
作为输入类型,我们通过说T extends {}
“暗示”它是一个对象。 U
是输出类型。 借助这些,我们可以表示selector
函数是需要T
并返回undefined的U
的东西。
Now if you attempt to write the same code as before with this definition of idx
, you will get a compile error:
现在,如果您尝试使用idx
定义编写与以前相同的代码,则会出现编译错误:
示例3:使用类型推断和泛型获取函数的返回类型 (Example 3: Using type inference and generics to get the return type of a function)
Suppose that I have a function, and I need to supply the consumer with the type of output. If I call this type FooOutput
, I’ll write something like:
假设我有一个函数,并且需要向消费者提供输出类型。 如果我将此类型FooOutput
,我将编写类似以下内容的内容:
But by using generics and type inference, I can write a ReturnType
generic type, that can “infer” the return type of a function:
但是,通过使用泛型和类型推断,我可以编写一个ReturnType
泛型类型,它可以“推断”函数的返回类型:
We’re playing with a T extends (...args: any[]) =>
any here. This just means tha
t T is a generic function type that takes any number of
any arguments and produces a value. Then we use it to in
fer another typ
e R, and return it.
我们在这里玩一个T extends (...args: any[]) =>
any。 这只是个手段a
吨T是一个通用的功能类型可以接收任意数量of
任何参数,并产生一个值。 然后,我们用它to in
FER另一个TY p
éR,并将其返回。
Using this, I avoid the need to write my return type in the above example manually. Since foo
is a function and I need that function’s type to use ReturnType
, I’ve to get the type of foo
by using typeof
.
使用此方法,可以避免在上面的示例中手动编写我的返回类型。 由于foo
是一个函数,我需要该函数的类型才能使用ReturnType
,所以我必须使用typeof
来获取foo
的类型。
工具箱中有用的实用程序? (Helpful utilities in my toolbox ?)
I use a bunch of these utilities in everyday programming. Most of the utility generics are defined in the typescript lib.es5.d.ts
over here. Some of my most-used ones include:
我在日常编程中使用了许多此类实用程序。 大多数实用程序泛型都在此处的打字稿lib.es5.d.ts
中定义。 我最常用的一些功能包括:
Hopefully, this helps you grasp Typescript generics a bit more. If you have questions, don’t hesitate to leave a question down below.
希望这可以帮助您更多地掌握Typescript泛型。 如果您有任何疑问,请不要在下面留下任何疑问。
泛型 typescript