You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何给封装combineLatest的自定义函数配置正确的TypeScript类型?

类型优化方案

可以通过 TypeScript 泛型 + 函数重载的方式匹配原生 combineLatest 的类型推导规则,完整保留输入源的静态类型:

优化思路

  • 定义两个函数重载分别匹配「单个Observable入参」和「Observable数组入参」两种调用场景
  • 用泛型动态捕获输入source的所有Observable的发射值类型
  • 最终返回值类型自动将observeAnimal$返回的Animal类型拼接在combineLatest结果元组的最后一位,和原生combineLatest行为完全一致

完整优化代码

import { Observable, combineLatest } from 'rxjs';

enum Animals {
    DOG,
    CAT
}

interface Animal {
    name: string,
    type: Animals
}

export function observeAnimal$(type: Animals): Observable<Animal> { 
// 实现逻辑
}

// 重载1:入参为单个Observable的场景
export function combineAnimal$<T>(source: Observable<T>, type: Animals): Observable<[T, Animal]>
// 重载2:入参为Observable数组的场景(TS4.0+ 可变元组泛型支持,可精准推导元组类型)
export function combineAnimal$<T extends Observable<any>[]>(source: [...T], type: Animals): Observable<[...{[K in keyof T]: T[K] extends Observable<infer U> ? U : never}, Animal]>
// 函数实现
export function combineAnimal$(source: Observable<any>[] | Observable<any>, type: Animals) {
    if(Array.isArray(source)) {
        return combineLatest([...source, observeAnimal$(type)]);
    } else {
        return combineLatest([source, observeAnimal$(type)]);
    }
}

使用效果示例

import { of } from 'rxjs';

// 单源调用场景
const user$ = of({id: 1, nickname: '阿明'});
const singleResult$ = combineAnimal$(user$, Animals.DOG);
// 自动推导类型:Observable<[{id: number; nickname: string}, Animal]>
singleResult$.subscribe(([user, animal]) => {
    // 此处user和animal都有完整的类型提示,不会丢失类型
})

// 数组源调用场景
const sourceList = [of(2023), of('测试文本'), of(true)] as const;
const arrResult$ = combineAnimal$(sourceList, Animals.CAT);
// 自动推导类型:Observable<[number, string, boolean, Animal]>

低版本TS兼容方案

如果你的TypeScript版本低于4.0,不支持可变元组泛型,可以使用简化的数组类型推导:

// 低版本TS重载2写法,返回联合类型数组
export function combineAnimal$<T>(source: Observable<T>[], type: Animals): Observable<(T | Animal)[]>

这种写法不能精准推导每个位置的类型,但也比any类型更安全。

内容的提问来源于stack exchange,提问作者Matteo Veraldi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:24:09