# 什么是泛型?

泛型指的是类型参数化,即将原来某种具体的类型进行参数化。设计泛型的目的在于有效约束类型成员之间的关系,比如函数参数和返回值、类或者接口成员和方法之间的关系。

定义的时候, 不确定类型 , 调用的时候能确定 类型的参数

# 泛型类型参数

function getValue(val: string): string {
  return val;
}

function getValue1(val: number): number {
  return val;
}

function getValue2(val: unknown): unknown {
  return val;
}

let g1: string = getValue("1");
let g2: number = getValue1(1);
let g3: unknown = getValue2(1);

function getValue3<T>(val: T): T {
  return val;
}

let g4: number = getValue3<number>(3);
let g5: string = getValue3<string>('4');

# 泛型类型

前面我们使用过Array<类型>来定义数组的类型,这里的Array也是一种类型。

在 TypeScript 中,类型本身就可以被定义为拥有不明确的类型参数的泛型,并且可以接收明确类型作为入参,从而衍生出更具体的类型。

// 定义数组类型
let arr: Array<number> = [1];
let arr1: Array<string> = [""];

// 类型别名
type typeFn<P> = (params: P) => P;
let fntype: typeFn<number> = (n: number) => {
  return n;
};

let fn1:typeFn<string> = (p: string):string => {
    return p;
} 
// 定义接口类型
interface TypeItf<P> {
  name: P;
  getName: (p: P) => P;
}

let t1: TypeItf<number> = {
  name: 123,
  getName: (n: number) => {
    return n;
  },
};

let t2: TypeItf<string> = {
  name: "123",
  getName: (n: string) => {
    return n;
  },
};

# 泛型约束

把泛型入参限定在一个相对更明确的集合内,以便对入参进行约束。

interface TypeItf<P extends string | number> {
  name: P;
  getName: (p: P) => P;
}

let t1: TypeItf<number> = {
  name: 123,
  getName: (n: number) => {
    return n;
  },
};

let t2: TypeItf<string> = {
  name: "123",
  getName: (n: string) => {
    return n;
  },
};