React.ChangeEvent<HTMLInputElement> 语法显示了所谓的Generic Type。此类型接收另一种类型作为“参数”以进一步更好地指定它。
将泛型类型与函数类似,但针对类型。我们用来接收一个或多个值并产生另一个值的函数。泛型类型是相似的,它们接收一个或多个类型并产生一个类型。仅泛型类型可能不足以表示某些东西,这取决于它是否使用可选参数声明(就像函数可能有也可能没有可选参数一样)。
这是一个更简单的泛型类型示例:Array<T>。这只是T[] 的另一种说法。例如,Array<number>。另一个非常常见的泛型类型是Promise<T>,它表示解析为T 的promise 的类型。
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 的语法相匹配,例如,我们有诸如ArrayList<String> 之类的泛型类型和诸如myFunc<SomeType>(a: SomeType) 之类的泛型函数。