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

TypeScript如何实现函数一个参数的类型依赖另一参数的取值?

问题根因

TypeScript 目前不支持对未实例化的泛型参数做关联窄化:你在函数内部对action参数做值判断时,TS 只会窄化action本身的类型,不会同步推导泛型参数K的实际类型,因此依赖K的LayoutType<K>始终处于未解析状态,无法根据分支自动匹配对应的类型,才会出现两个分支都识别不到h属性的问题。

解决方案

推荐使用可辨识联合元组重写函数参数定义,TS 对联合类型的窄化能力可以完美匹配你的需求:

export interface LaneLayout {
  i: number;
  x: number;
  y: number;
  w: number;
  h: number;
  lane_content: string;
  project_id: number;
}

export type Action = "modify" | "create";

export type ModifiedLaneLayout = Omit<
  LaneLayout,
  "project_id" | "lane_content"
>;
export type CreatedLaneLayout = Pick<LaneLayout, "x" | "y">;

// 定义参数的可辨识联合元组
type ModifyBoxParams = 
  | [action: "modify", layout: ModifiedLaneLayout]
  | [action: "create", layout: CreatedLaneLayout]

export function modifyBox(...[action, layout]: ModifyBoxParams): void {
  if (action === "modify") {
    layout.h; // 可正常访问h属性,类型正确
  } else {
    layout.h // 此处TS会抛出属性不存在的错误,符合预期
  }
}

如果需要保留原有泛型写法,也可以在分支内手动添加类型断言使用,但是类型安全性略低于上述联合元组方案:

export type LayoutType<T extends Action> = T extends "modify"
  ? ModifiedLaneLayout
  : T extends "create"
  ? CreatedLaneLayout
  : never;

export function modifyBox<K extends Action>(
  action: K,
  layout: LayoutType<K>
): void {
  if (action === "modify") {
    (layout as ModifiedLaneLayout).h; // 手动断言后可正常访问
  } else {
    (layout as CreatedLaneLayout).x // 类型正常
  }
}

内容的提问来源于stack exchange,提问作者Tom van Nes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:51:02