函数

当我不知道返回值或者传入参数人的类型的时候,经常会使用any类型来定义函数:

  1. function identity(arg: any): any {
  2. return arg;
  3. }

使用any类型会导致这个函数可以接收任何类型的arg参数,这样就丢失了一些信息:传入的类型与返回的类型应该是相同的。如果我们传入一个数字,我们只知道任何类型的值都有可能被返回。
因此,我们需要一种方法使返回值的类型与传入参数的类型是相同的。 这里,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。

  1. function identity<T>(arg: T): T {
  2. return arg;
  3. }

使用

  1. let output = identity<string>("myString"); // type of output will be 'string'

泛型类

泛型类看上去与泛型接口差不多。 泛型类使用(<>)括起泛型类型,跟在类名后面。

  1. class GenericNumber<T> {
  2. zeroValue: T;
  3. add: (x: T, y: T) => T;
  4. }
  5. let myGenericNumber = new GenericNumber<number>();
  6. myGenericNumber.zeroValue = 0;
  7. myGenericNumber.add = function(x, y) { return x + y; };

GenericNumber类的使用是十分直观的,并且你可能已经注意到了,没有什么去限制它只能使用number类型。 也可以使用字符串或其它更复杂的类型。

  1. let stringNumeric = new GenericNumber<string>();
  2. stringNumeric.zeroValue = "";
  3. stringNumeric.add = function(x, y) { return x + y; };
  4. console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));

我们来看下 react的Componet是如何实现的:

  1. class Component<P, S> {
  2. static contextType?: Context<any>;
  3. context: any;
  4. constructor(props: Readonly<P> | P);
  5. constructor(props: P, context: any);
  6. setState<K extends keyof S>(
  7. state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
  8. callback?: () => void
  9. ): void;
  10. forceUpdate(callback?: () => void): void;
  11. render(): ReactNode;
  12. refs: {
  13. [key: string]: ReactInstance
  14. };
  15. }

泛型约束

  1. function loggingIdentity<T>(arg: T): T {
  2. console.log(arg.length); // Error: T doesn't have .length
  3. return arg;
  4. }

相比于操作any所有类型,我们想要限制函数去处理任意带有.length属性的所有类型。 只要传入的类型有这个属性,我们就允许,就是说至少包含这一属性。 为此,我们需要列出对于T的约束要求。
为此,我们定义一个接口来描述约束条件。 创建一个包含.length属性的接口,使用这个接口和extends关键字来实现约束.

  1. interface Lengthwise {
  2. length: number;
  3. }
  4. function loggingIdentity<T extends Lengthwise>(arg: T): T {
  5. console.log(arg.length); // Now we know it has a .length property, so no more error
  6. return arg;
  7. }