关于 typescript 泛型 | 青训营笔记

73 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第 9 天

先说说用 typescript 的好处。

众所周知 js 是弱类型语言,也就是说 js 的变量并非是从定义的那一刻起就固定好的,比如 C,当你想要定义一个变量必须先指定类型,如 int a,但 js 就不一样了,let a,可以给 a 赋值数字、字符串、数组或者对象方法等任何类型,而且还有一些运算过程中的转换比如 '1' + 1 === '11'。这在某些情况下的确方便不少,但也会引起 bug,比如明明想计算数字之间的加法运算,结果却成为字符串的拼接,有时 js 这种“智能”的解释结果可能并非是我们希望的。而 typescript 在一定程度上可以避免这种情况的发生,避免方法的不正当调用而产生 bug。

image.png

还有一点就是很多 IDE 会提示传参,让我们直观看到某个方法可以传哪些参数,哪些是必须的那些是非必须的。

那么问题来了,如果有个方法,无法在定义的时候确定传参是什么类型,只有使用时会确定,该怎么办呢?

使用泛型。

泛型接口

用于接口。比如有这样一个场景,有个 state 的类型是 IPageInfo,但初始化的时候可能是 null,之后可能会被赋值,那么它的类型可能是 <IPageInfo | null>

interface IPageInfo {
  title: string
  platform: PC | H5
}

// ...
const [ pageInfo, setPageInfo ] = useState<IPageInfo | null>(null)
// ...

使用泛型的话就相当于 ↓

interface IPageInfo {
  title: string
  platform: PC | H5
}
type Empty<T> = T | null
// ...
const [ pageInfo, setPageInfo ] = useState<Empty<IPageInfo>>(null)
// ...

泛型约束

用于方法。方法定义的时候先不指定传参类型和返回类型,在使用时临时指定传参类型。

比如下列例子,log 函数如果传参只定义 string,那么 number 类型是无法使用 log 方法的。这使得 log 方法不具备普适性无法复用。

function log(arr: string): string{
  console.log('入参是:',arr)
  return arr
}

log('1')
log(2) // 类型“number”的参数不能赋给类型“string”的参数。

但如果使用泛型,在使用的时候再决定传入参数的话,就可以 log 任何类型了。

function log<T>(arr: T): T{
  console.log('入参是:',arr)
  return arr
}

log<string>('1')
log<number>(2)

参考:《一文读懂 TypeScript 泛型及应用( 7.8K字)》