我很难理解Typescript尖括号后面的目的。
通常,它们用于泛型。对我来说,这对于功能来说是最清楚的。例如,如果您要使某个函数具有更高的可重用性(或“泛型”),则可以在函数名称之后应用它们,如下所示:
function identity<T>(arg: T): T {
return arg;
};
这可以增强类型安全性,同时还允许您将此函数用于多种类型。
但是,在其他情况下,<
和>
括号在 其他类型之后出现,例如在以下事件处理程序中:
const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
const val = e.currentTarget.value;
setWord(val);
};
通过查看Typescript的自动完成功能,React.ChangeEvent
会显示以下内容:React.ChangeEvent<Element>
<Element>
是什么意思?它也是通用的吗?HTMLInputElement
,如果是,那是接口吗?React.ChangeEvent
类型之后通过 传递,而对于函数,则传递了T
泛型在函数主体之前?答案 0 :(得分:2)
React.ChangeEvent<HTMLInputElement>
语法显示所谓的Generic Type。此类型会收到另一种类型的“参数”,以进一步更好地指定它。
认为泛型类似于函数,只是类型。我们用来接收一个或多个值并产生另一个值的函数。泛型类型相似,它们接收一个或多个类型并产生一个类型。单独的泛型类型可能不足以表示某些东西,这取决于是否用可选参数声明了它(就像一个函数可能具有可选参数一样)。
这是一个通用类型简单得多的示例:Array<T>
。这只是T[]
的另一种说法。例如,Array<number>
。另一个非常常见的泛型类型是Promise<T>
,它表示解析为T
的承诺的类型。
Promise
是一个通用类型的好例子,其参数是必需的:
// --------------------------------------
// | interface Promise<T> |
// --------------------------------------
// | Represents the completion of an |
// | asynchronous operation |
// --------------------------------------
// | Generic type 'Promise<T>' requires |
// | 1 type argument(s). ts(2314) |
// --------------------------------------
// ^
// |
// |
type X = Promise;
假设您要以{ foo: something }
的形式表示一个对象,其中任何对象都可以是您想要的。您可以使用通用类型来做到这一点:
type Foo<SomeType> = {
foo: SomeType;
};
// Now you can declare specific types
type FooWithString = Foo<string>;
// equivalent of:
// type FooWithString = { foo: string };
type FooWithNumber = Foo<number>;
// equivalent of:
// type FooWithString = { foo: number };
如果我们想将此SomeType
设为可选的类型参数,以便我们的通用类型Foo
也可以单独使用(无需通过尖括号传递类型),我们只需决定我们希望其默认类型是什么(类似于我们为普通功能选择默认值的方式):
type Foo<SomeType = Date> = {
foo: SomeType;
};
现在我们可以在不使用尖括号的情况下使用Foo
了-等同于进行Foo<Date>
。
您可以在TypeScript reference for Utility Types中找到一些有趣的类型示例。
明确回答您的问题:
1。。<Element>
显示您正在悬停的通用类型(即React.ChangeEvent
)收到一个类型参数,而来自React团队的人创建了该通用类型决定将此参数称为Element
。
Foo<number>
上,它将显示Foo<SomeType>
,因为这就是我声明类型的方式。 2a。是,我们将HTMLInputElement
作为参数传递给通用类型React.ChangeEvent
。将React.ChangeEvent
看作是一个“类型函数”,它接受一个类型参数并“返回”另一个类型。因此,我们将HTMLInputElement
赋予React.ChangeEvent
,以便得到的类型React.ChangeEvent<HTMLInputElement>
指定我们想要的内容。
2b。。是否作为界面无关紧要。 interface
只是一种语法,用于声明与标准type Foo = /* ... */
相比具有一些怪癖的类型。现在不用担心这些细节。
3。。这正是TypeScript开发人员确定语法的方式。例如,它与Java的语法相匹配,在Java中,我们具有诸如ArrayList<String>
之类的通用类型和诸如myFunc<SomeType>(a: SomeType)
之类的通用函数。
答案 1 :(得分:1)
ChangeEvent
就像可以向函数传递类型一样,因此您正在向其中传递具体类型。您也可以将具体类型传递给函数-identity<MyType>(myArg)
,尽管您可能不需要,因为您可以从传递的参数中推断出类型,因为它们都共享T
。
区别在于ChangeEvent
不能从参数推断类型,因为它不是函数,因此您需要显式为其指定一个。
HTMLInputElement
可以是type
或interface
。 ChangeEvent
会因HTML元素类型的不同而有所不同(对input
的更改与对select
的更改不同),因此您传入了要获取的元素类型完成最后的界面。