zl程序教程

您现在的位置是:首页 >  其他

当前栏目

理解泛型调用和函数调用签名

2023-02-26 09:51:51 时间

这里通过五个示例逐步理解泛型调用和函数调用签名

/*
 * @Author: Zheng Lei
 * @Email: baimoc@163.com
 * @Date: 2023-01-18 16:29:21
 * @LastEditTime: 2023-01-18 17:13:43
 * @FilePath: \baimo_music\demo.ts
 */

// 一、--------------------------------------------------------
// () 内是函数参数类型约束
// : 后是函数返回值类型约束
interface IFnCall {
  (name: string, age: number): string
}

// IFnCall 是函数调用签名
const foo: IFnCall = function (name, age) {
  return name + age
}
// 函数调用
foo('tom', 10)

// --------------------------------------------------------

// 定义第一个参数为一个函数,并且该函数返回值的类型为 string
interface IFnCall2 {
  (fn: () => string, age: number): string
}

const foo2: IFnCall2 = function () {
  return ''
}

foo2(() => {
  return ''
}, 10)

// ----------------------------------------------------------
// <MyType> 代表函数调用时的类型约束
// 其中第一个参数为一个函数,并且返回值的类型为 MyType
interface IFnCall3 {
  <MyType>(fn: () => MyType, age: number): string
}

const foo3: IFnCall3 = function () {
  return ''
}

foo3<number>(() => {
  return 11
}, 10)

// 报错写法, MyType 类型不一致
// foo3<string>(() => {
//   return 11
// }, 10)

// 正确写法
foo3<number>(() => {
  return 11
}, 10)

// 不传入类型,则会进行类型推断
foo3(() => {
  return 11
}, 10)

// ----------------------------------------------------------
// <MyType> 代表函数调用时的类型约束
// 其中第一个参数为一个函数,并且返回值的类型为 MyType
// IFnCall4 的返回值类型也为 MyType
interface IFnCall4 {
  <MyType>(fn: () => MyType, age: number): MyType
}

const foo4: IFnCall4 = function (fn) {
  return fn()
}

// 这里对 foo4 的返回值进行类型约束,
foo4<number>(() => {
  return 11
}, 10)

// -----------------------------------------------------------
// <MyType> 代表函数调用时的类型约束
// <IRoot> 代表函数定义时的类型约束
interface IFnCall5<IRoot> {
  <MyType>(fn: (name: IRoot) => MyType, age: number): MyType
}

const foo5: IFnCall5<string> = function (fn) {
  return fn('Tom')
}

// 类型推断过程
// IFnCall5 的 IRoot 定义 string 类型
// 根据 fn 的 name 的 IRoot 类型 推断 fn 函数的返回值 MyType 为 string 类型
// 得到 foo5 函数调用时类型也为 string
// 得到 foo5 函数返回值类型也为 string
// 因此,可以通过fn参数一的返回值推断出 IFnCall5 的返回值类型
const res = foo5((name) => {
  return name
}, 10)

console.log(res)