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

如何在TypeScript函数中根据children参数限制initial参数类型?

用TypeScript限制initial参数必须是children数组中的元素

先看我原本的代码:

interface INavigation {
  children: string[];
  initial: string;
}

function navigation({ children, initial }: INavigation) {
  return null
}

我希望把initial参数的输入限制为children数组里的元素,比如:

// 合法调用
navigation({ children: ["one", "two", "three"], initial: "one" })
navigation({ children: ["one", "two", "three"], initial: "two" })

// 应该抛出类型错误:Type 'four' is not assignable to type 'one' | 'two' | 'three'.
navigation({ children: ["one", "two", "three"], initial: "four" })

目前我只能想到在函数内部做运行时校验的方案:

function navigation({ children, initial }: INavigation) {
   
  if (!children.includes(initial)) {
    throw new Error(`${initial} is invalid. Must be one of ${children.join(',')}.`)
  }
  return null
}

解决方案:用TypeScript泛型实现编译时约束

完全可以通过TypeScript的泛型在编译阶段就完成这个限制,同时也可以保留运行时校验兼容非TS场景。

直接实现泛型函数

function navigation<T extends string>({ children, initial }: { children: T[], initial: T }) {
  // 可选:保留运行时检查,防止非TypeScript调用传入非法值
  if (!children.includes(initial)) {
    throw new Error(`${initial} is invalid. Must be one of ${children.join(',')}.`)
  }
  return null
}

复用泛型接口的写法

如果需要复用这个类型定义,可以改成泛型接口:

interface INavigation<T extends string> {
  children: T[];
  initial: T;
}

function navigation<T extends string>(props: INavigation<T>) {
  if (!props.children.includes(props.initial)) {
    throw new Error(`${props.initial} is invalid. Must be one of ${props.children.join(',')}.`)
  }
  return null
}

这样调用时,TypeScript会自动根据children的字面量数组推断出T的联合类型(比如"one" | "two" | "three"),initial只能传入这个范围内的值,非法值会直接在编译阶段报错,不需要等到运行时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:05:37