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

如何声明TypeScript类型确保数组中函数输入输出类型衔接?

类型声明:确保数组中函数的输入输出类型链式匹配

问题描述

想要声明一个类型,确保数组中某个函数的输出类型与下一个函数的输入类型完全一致。

示例数组:

const mappings = [
     (x: EditorState) => editorState.getCurrentContent(x) as ContentState,
     (x: ContentState) => convertToRaw(x) as RawDraftContentState,
     (x: RawDraftContentState) => JSON.stringify(x) as string,
     (x: string) => gzipString(x)
 ]

该类型大概率需要同时具备递归性与泛型特性。

编辑补充:若能给出覆盖一定长度列表所有可能情况的方案即可,这应该是可行的吧?

解决方案

递归泛型实现方案

我们可以通过递归泛型约束函数数组的链式类型匹配,确保每一个函数的输出与下一个函数的输入类型严格对齐:

// 基础函数类型:接收输入I,返回输出O
type Func<I, O> = (input: I) => O;

// 递归定义的函数链类型,支持任意长度
type FunctionChain<PrevInput> = [
  Func<PrevInput, infer NextOutput>,
  ...FunctionChain<NextOutput>
] | [];

使用时只需指定初始输入类型,TypeScript会自动校验整个链的类型匹配:

// 声明以EditorState为初始输入的函数链类型
type EditorStateProcessingChain = FunctionChain<EditorState>;

// 若函数输入输出不匹配,TypeScript会直接报错
const mappings: EditorStateProcessingChain = [
  (x: EditorState) => editorState.getCurrentContent(x) as ContentState,
  (x: ContentState) => convertToRaw(x) as RawDraftContentState,
  (x: RawDraftContentState) => JSON.stringify(x) as string,
  (x: string) => gzipString(x)
];

固定长度覆盖方案

如果不需要支持无限长度,只需覆盖特定范围的函数链长度(比如1-4个函数),可以手动定义不同长度的链类型并合并为联合类型,这种方式类型检查更高效:

type Func<I, O> = (input: I) => O;

// 长度为1的函数链
type Chain1<I, O> = [Func<I, O>];
// 长度为2的函数链:中间类型M衔接输入I和输出O
type Chain2<I, M, O> = [Func<I, M>, Func<M, O>];
// 长度为3的函数链:两个中间类型衔接
type Chain3<I, M1, M2, O> = [Func<I, M1>, Func<M1, M2>, Func<M2, O>];
// 长度为4的函数链:三个中间类型衔接
type Chain4<I, M1, M2, M3, O> = [Func<I, M1>, Func<M1, M2>, Func<M2, M3>, Func<M3, O>];

// 合并为支持1-4长度的联合类型
type FixedLengthChain<I, FinalOutput> = 
  Chain1<I, FinalOutput> | 
  Chain2<I, infer M, FinalOutput> | 
  Chain3<I, infer M1, infer M2, FinalOutput> | 
  Chain4<I, infer M1, infer M2, infer M3, FinalOutput>;

使用示例:

// 指定初始输入为EditorState,最终输出为gzipString的返回类型
const mappings: FixedLengthChain<EditorState, ReturnType<typeof gzipString>> = [
  (x: EditorState) => editorState.getCurrentContent(x) as ContentState,
  (x: ContentState) => convertToRaw(x) as RawDraftContentState,
  (x: RawDraftContentState) => JSON.stringify(x) as string,
  (x: string) => gzipString(x)
];

方案对比

  • 递归泛型方案:支持任意长度的函数链,但在链极长时可能出现类型推导性能下降
  • 固定长度方案:类型检查速度更快、逻辑更直观,适合提前明确函数链最大长度的场景

内容的提问来源于stack exchange,提问作者Sp Jan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:50:17