TypeScript 类型推导真强大。

zhbhun · 2024-10-18 14:18:06 · 117 次点击
最近在学习开发客户端相关的功能,发现 Kotlin 和 Swift 要实现泛化的高阶函数不太容易。比如我要实现一个高阶函数,需要将传入的一个 async 函数转为串行执行的函数,必须等待前一个任务完成后才能开始下一个。使用 TS 可以这么做:

```ts
function sequentialize<T extends (...args: any[]) => Promise<any>>(
  asyncFn: T
): (...args: Parameters<T>) => ReturnType<T> {
  let queue: Promise<void> = Promise.resolve(); // 初始化队列
  return function (...args: Parameters<T>): ReturnType<T> {
    const result = queue.then(() => asyncFn(...args)); // 将异步任务添加到队列中
    queue = result.catch(() => {}); //捕获错误,防止队列中
    return result as ReturnType<T>; //确保返回类型与原始函数一致
  };
}

async function plus(a: number, b: number): Promise<number> {
  await new Promise<void>((resolve) => {
    setTimeout(() => {
      resolve();
      console.log(performance.now(), a, b);
    }, 1000);
  });
  return a + b;
}

const sequentializePlus = sequentialize(plus);

```

但这在 Swift 和 Kotlin 里不太好处理,它们没法传入动态的函数,并包装后返回同类型的函数。想问下,如果像 Swift 和 Kotlin 这样的强类型语言要实现这样的语法,是否会存在什么限制?是否是因为 TS 编译后的 JS 是动态类型的,才支持这种类型推导(运行不会出问题),而 Swift 和 Kotlin 无法做到?
举报· 117 次点击
登录 注册 站外分享
8 条回复  
hronro 小成 2024-10-18 14:55:47
你这有点题不对文, [类型推导] 指的是不用写类型标注,编译器就能自动推导出变量的类型,TS 在这方面被 OCaml 秒成渣渣。
至于你文中说的这种情况,只要是类型系统强大一点或者支持函数为一等公民的都能实现,和强弱类型没有任何关系,像 Rust 这种更偏底层的语言也能实现你之前提到的特性。
dejavuwind 初学 2024-10-18 14:38:00
Kotlin 应该也能实现吧? https://book.kotlincn.net/text/lambdas.html
类似于 Java 的 Functional Interface ?
wlingxiao 小成 2024-10-18 14:33:55
kotlin 了解的不多不确定能能不能做到,但是同为 jvm 上的语言 scala 可以做到,这些都是编译器的魔法,和运行时没关系。
换个思路想,js 代码也是可以跑在 jvm 上的。
maichael 小成 2024-10-18 14:27:01
JS 能这样实现,不是因为它强大,而恰恰是因为它够“弱”才能这么做;跟 Typescript 就更没啥直接关系了。
jy02534655 小成 2024-10-18 14:23:55
这个应该和 TypeScript 关系不大吧,js 特性,js 是弱语言类型
返回顶部