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

如何在TypeScript中实现Rust风格match函数并正确定义其类型

简化版Rust match语法的TypeScript类型实现

最终实现代码

export function match<
  // 约束匹配值的类型为字符串或数字字面量联合
  T extends string | number,
  // 约束配置对象:key必须覆盖T的所有成员,value必须是无参函数
  Options extends Record<T, () => unknown>
>(value: T, options: Options): ReturnType<Options[T]> {
  // 类型断言安全,泛型约束已保证options[value]一定是符合要求的函数
  return options[value]() as ReturnType<Options[T]>
}

规则匹配说明

  • 穷尽key检查:因为Options被约束为Record<T, ...>,T是传入匹配值的所有可能类型的联合,如果配置对象缺少任意一个T中存在的key,TypeScript会直接抛出属性缺失错误。
  • 函数类型校验:配置对象的value被约束为() => unknown,如果传入非函数类型的值,TypeScript会抛出类型不匹配错误。
  • 返回值类型自动推导:通过ReturnType<Options[T]>自动聚合所有分支函数的返回值类型,返回值就是所有分支返回值的联合类型,无需手动声明。

效果验证

正常使用场景

const value = Math.random() > 0.5 ? 1 : 'foo'
 
const result = match(value, {
  1: () => 100,
  foo: () => 'F'
})
// result 类型自动推导为 100 | 'F',符合预期

错误触发场景

  1. 缺少匹配key:
// 报错:类型 "{ 1: () => number; }" 缺少属性 "foo",类型 "Record<1 | "foo", () => unknown>" 需要该属性
const result = match(value, {
  1: () => 100
})
  1. 配置项不是函数:
// 报错:不能将类型“number”分配给类型“() => unknown”
const result = match(value, {
  1: 100,
  foo: () => 'F'
})

注意事项

原实现中使用了case作为参数名,case是JavaScript/TypeScript的保留关键字,会触发语法错误,因此实现中替换为了value作为参数名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:36:04