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

TypeScript中以数组值作为关联属性联合类型的问题

实现方案

可以实现,核心要解决两个类型推断问题:一是传入自定义perPageVariants时,TS默认会把数组字面量拓宽为number[],导致联合类型校验失效;二是as const生成的只读元组和可变数组类型约束不兼容。

完整可运行代码

// 抽离全局默认配置,保留as const保证精确字面量类型
const defaultPerPageVariants = [10, 25, 50, 100, 200] as const;

type PaginationProps<P extends readonly number[]> = {
  // 可变元组写法[...P]触发字面量精确推断,避免数组被拓宽为number[]
  perPageVariants?: [...P];
  perPageDefault?: P[number];
};

const Pagination = <P extends readonly number[] = typeof defaultPerPageVariants>(
  props: PaginationProps<P>
) => {
  const {
    perPageVariants = defaultPerPageVariants as [...P],
    perPageDefault = perPageVariants[0],
  } = props;

  return null;
};

关键逻辑说明

  • 泛型约束从number[]改为readonly number[]:TS中readonly number[]是所有数字数组(可变/只读)的父类型,既兼容用户传入的普通数组,也兼容as const生成的只读默认配置,解决只读类型赋值报错的问题。
  • perPageVariants类型写为[...P]:可变元组展开语法会提示TS不要将传入的数组字面量拓宽为宽泛的number[]类型,而是精确推断为传入值的字面量元组,这样P[number]就能拿到传入选项的精确数字联合类型,实现动态校验。
  • 默认值处的as [...P]类型断言是安全的:默认配置本身符合泛型P的类型约束,仅用于消弭只读元组赋值给可变元组位置的类型提示,不会影响运行时逻辑。

校验效果验证

// ✅ 合法:不传自定义选项时,perPageDefault仅允许默认值列表内的数字
<Pagination perPageDefault={10} />
// ❌ 类型错误:1000不在默认选项列表中
<Pagination perPageDefault={1000} />

// ✅ 合法:自定义选项下,perPageDefault允许传入自定义列表内的值
<Pagination perPageVariants={[123, 456]} perPageDefault={123} />
// ❌ 类型错误:100不在自定义选项[123,456]中,符合预期
<Pagination perPageVariants={[123, 456]} perPageDefault={100} />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:45:37