前言TS绝非为了炫技的存在, 一切为了类型安全, 牢记这句话, 牢记这句话, 牢记这句话!!!感谢林不渡和光神大佬, 本文基本上都是从大佬们那里学来的。
一道开胃菜function memoize any>(fn: T) { const cache = new Map() return (...args: Parameters) => { const key = JSON.stringify(fn) if (cache.has(key)) { return cache.get(key) } const result = fn(...args) cache.set(key, result) return result }}const add = (a: number, b: number) => a + bconst memoAdd = memoize(add)console.log(memoAdd(1, 2)) // 3console.log(memoAdd(1, 2)) // 3
上面这个缓存函数的有个泛型T, 泛型T被约束为是一个可以是任意类型参数和返回任意类型的函数, 函数被调用时才明确知道T的类型, 比如下面的add函数, 这个时候TS类型就自动推导T是一个a、b参数类型为number返回一个number的函数, 我们看缓存函数内部返回一个函数接收的参数类型应该和T的参数类型一致, 这个时候可以使用TS内置的工具类型Parameters, 它可以返回一个函数类型的参数数组类型, 所以我们typeof fn, 就可以拿到fn的类型, 或者直接使用Parameters。
我们来看看Parameters是怎么实现的:
type Parameters any> = T extends (...args: infer P) => any ? P : never;
Parameters工具类型接收一个泛型T被约束为可以是任意的函数类型, 后面用了infer类型推导, 可以在类型被使用时推导出具体的类型, T如果是(...args: infer P) => any的子类型, 就返回P, 否则返回never(表示永不可达)。
不熟悉这种语法没关系, 我们把TS的内置类型都实现一遍,熟能生巧。
TS内置类型工具Awaited// 基础用法type promise = Promisetype p = Awaited // string
// 定义一个返回 Promise 的函数function fetchData(): Promise { return new Promise((resolve) => { setTimeout(() => { resolve('成功啦啦啦'); }, 1000); });}// 使用 Awaited 获取 Promise 结果的类型type ResultType = Awaited