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

TypeScript中如何约束Select组件的defaultValue为options的可选值

实现方案

核心思路是通过泛型自动推断传入的options数组的value类型,将defaultValue的类型约束为所有options的value组成的字面量联合类型,即可实现非法值的类型报错。


第一步:定义泛型Props和组件

import type { ReactNode } from 'react'

// 定义Option的基础类型约束,可根据业务需求扩展value支持的类型
type OptionBase = {
  value: string | number | boolean
  label: ReactNode
}

// Select组件的泛型Props
type SelectProps<T extends OptionBase> = {
  // 加readonly兼容as const生成的只读数组类型
  options: readonly T[]
  defaultValue: T['value']
  // 其他业务需要的Props可以在这里追加,示例:
  onChange?: (value: T['value']) => void
  placeholder?: string
}

// 泛型Select组件实现
function Select<T extends OptionBase>(props: SelectProps<T>) {
  // 组件内部逻辑省略
  return <select>{/* 渲染逻辑 */}</select>
}

// 如果你习惯用箭头函数写法,直接这么写就行,不需要套React.FC(React.FC不支持直接传递泛型)
const SelectArrow = <T extends OptionBase>(props: SelectProps<T>) => {
  return <select>{/* 渲染逻辑 */}</select>
}

第二步:使用测试

和你给出的示例用法完全匹配:

const countryOptions = [
  {
    value: "au",
    label: "Australia",
  },
  {
    value: "nz",
    label: "New Zealand",
  }
] as const;

// ✅ 合法写法,无类型报错
<Select options={countryOptions} defaultValue="au" />

// ❌ 触发类型报错:类型"foo"不能分配给类型"au" | "nz"
<Select options={countryOptions} defaultValue="foo" />

注意事项

如果不使用as const声明options数组,TS会默认把value的类型推断为通用的string而非"au" | "nz"这类字面量联合类型,就不会触发非法defaultValue的类型校验,所以要实现这个效果必须给options加上as const声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:45:02