如何让TypeScript动态数组的construct函数参数获得正确类型?
动态追踪add元素类型的链式调用类型标注
你写的这段TypeScript代码,想通过wrapper创建的实例用add添加任意类型元素,同时希望construct的匿名函数参数能根据add的元素顺序获得精准的类型标注,但当前用单一泛型的方式做不到——因为泛型T会被推断成所有add元素的联合类型,没法区分每个参数的具体类型。
解决方案代码
const wrapper = <T extends unknown[] = []>() => { const arr: T = [] as T; const construct = (func: (...args: T) => void) => { func(...arr); }; const add = <U>(x: U) => { arr.push(x as T[number]); return wrapper<[...T, U]>(); }; return { add, construct }; }; const w = wrapper(); w.add(1) .add("2") .add({ a: 1 }) .construct( // 现在a自动标注为number,b为string,c为{a: number} (a, b, c) => { // 可以放心使用类型专属方法 console.log(a.toFixed(), b.length, c.a); } );
核心思路
- 把原来的单一泛型
T换成元组类型来追踪每次add的元素类型,初始元组为空数组[]。 - 每次调用
add时,通过泛型U捕获当前添加元素的类型,然后返回一个新的wrapper实例,泛型参数更新为[...T, U]——相当于在原元组末尾追加新的元素类型。 construct方法直接把元组T作为函数的剩余参数类型,这样展开后就完全匹配add调用的顺序和每个元素的具体类型。
内容的提问来源于stack exchange,提问作者Filip Micanek
相关产品推荐
相关产品推荐

