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

TypeScript中数组类型窄于查询类型时如何正确使用indexOf方法

错误原因

你遇到的类型报错是因为:
NAVIGABLE_STATES 是三个可导航状态字面量组成的只读数组,其元素类型为 "show_instructions" | "lift_box" | "turn_box" 窄联合类型。而传入 indexOf 的参数 state 是更宽的 OverallState 类型,额外包含了不可导航的 "wait_for_connection"、"calibrate" 两种状态,TS 不允许将宽类型直接传入要求窄类型的入参,因此抛出错误:

Argument of type 'OverallState' is not assignable to parameter of type '"show_instructions" | "lift_box" | "turn_box"'.
Type '"wait_for_connection"' is not assignable to type '"show_instructions" | "lift_box" | "turn_box"'.

解决方案

方案1:添加类型守卫+运行时边界校验(推荐)

通过类型守卫先判断当前状态是否可导航,同时补充边界处理逻辑,避免运行时出现越界取到undefined的问题:

const NAVIGABLE_STATES = ["show_instructions", "lift_box", "turn_box"] as const;
// 抽离可导航状态类型,方便复用
type NavigableState = typeof NAVIGABLE_STATES[number];

type OverallState = 
  | "wait_for_connection"
  | "calibrate"
  | NavigableState;

// 类型守卫:运行时判断状态是否属于可导航范围,同时收窄类型
function isNavigableState(state: OverallState): state is NavigableState {
  return (NAVIGABLE_STATES as readonly string[]).includes(state);
}

function navigate(state: OverallState, direction: -1 | 1): OverallState {
  // 不可导航状态直接返回原值
  if (!isNavigableState(state)) return state;

  const currentIdx = NAVIGABLE_STATES.indexOf(state);
  const nextIdx = currentIdx + direction;
  // 越界处理:超出首尾时停在边界状态,可按需修改为循环跳转逻辑
  if (nextIdx < 0) return NAVIGABLE_STATES[0];
  if (nextIdx >= NAVIGABLE_STATES.length) return NAVIGABLE_STATES.at(-1)!;
  return NAVIGABLE_STATES[nextIdx];
}

方案2:直接类型断言(适合调用前已做入参校验的场景)

如果你的业务逻辑已经保证调用navigate时传入的一定是可导航状态,可以直接用类型断言绕过类型检查,同时建议补充越界判断避免运行时异常:

function navigate(state: OverallState, direction: -1 | 1): OverallState {
  const currentIdx = NAVIGABLE_STATES.indexOf(state as NavigableState);
  const nextIdx = currentIdx + direction;
  return nextIdx >= 0 && nextIdx < NAVIGABLE_STATES.length 
    ? NAVIGABLE_STATES[nextIdx] 
    : state;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:06:04