泛型知多少

大纲

  • 值与类型
  • 泛型的本质
  • 泛型的种类
  • 泛型约束

TS 究竟为我们做了啥?

1. TS 提供内置类型给我们使用

2. 另外还提供了类型推导和校验的能力

 

3.   同时提供泛型给我们开发自己的类型

0. 值与类型

if (person.isVIP) {
    console.log('VIP')
}
if (cnt > 5) {
    // do something
}

const personNames = persons.map(p => p.name)
...

类型

 

number

string

boolean

...

1. TS 提供内置类型给我们使用
function t(name: string) {
  return `hello, ${name}`;
}
t("lucifer");

字符串 “lucifer” 是 string 类型的一个具体。 在这里 “lucifer” 就是值,而 string 就是类型。

TS 明白 “lucifer” 是 string 集合中的一个元素,因此上面代码不会有问题,但是如果是这样就会报错:

t(123);
2. 另外还提供了类型推导和校验的能力
v = getValue(); // will return 'lucifer' by ast
if (typeof v === "string") {
  // ok
} else {
  throw "type error";
}
3.同时提供泛型给我们开发自己的类型

什么是泛型?

泛泛的类型

泛型就是对类型编程
enum Sex {
  Man,
  Woman,
  UnKnow,
}
interface Person {
  name: string;
  sex: Sex;
  age: number;
}
interface MarketPerson {
  name?: string;
  sex?: Sex;
  age?: number;
  phone: string;
}

突然有一天,有一个新的需求,也需要 Person,但是 name ,sex,age 不是必填了,并且多了个 phone 字段

当我们系统存在如下的类型

应该怎么办?

复制粘贴么?

可以,但是没有必要~

如果我们直接能对类型进行编程?

function Partial(Type) {
    type ans = 空类型
    for(k in Type) {
        空类型[k]  = makeOptional(Type, k)
    }
    return ans
}

type PartialedPerson = Partial(Person)

或许不难写出如下的代码

2. 上面代码是基于运行时的, 而TS不应该依赖运行时

1. 怎么给 Partial 添加类型签名?

// 可以看成是上面的函数定义,可以接受任意类型。由于是这里的 “Type” 形参,因此理论上你叫什么名字都是无所谓的,就好像函数定义的形参一样。
type Partial<T> = { [P in keyof T]?: T[P] };
// 可以看成是上面的函数调用,调用的时候传入了具体的类型 Person

type PartialedPerson = Partial<Person>

 

TS 官方是如何解决这个问题的?

泛型为什么使用尖括号

泛型的种类

Title Text

泛型的参数类型 - 泛型约束

用 extend

Next

  • 常见的泛型
  • 泛型中的类型推导与默认参数
  • 高级泛型 - 嵌套与递归
  • 泛型工具及原理
  • 用泛型打造通用智能提示功能

Thanks~

泛型知多少

By lucifer

泛型知多少

  • 605