如何在TypeScript中限制类的数字索引签名仅允许0和1两个值?
你可以结合编译时类型约束和运行时属性拦截实现需求,完整实现方案如下:
type AllowedIndex = 0 | 1 class TupleWrapperClass { // 编译层面限制仅允许0、1作为数字索引 [key: AllowedIndex]: number // 内部私有存储实际值,避免外部直接篡改 #store: [number, number] constructor(value1: number, value2: number) { this.#store = [value1, value2] // 返回代理实例拦截所有属性访问,实现运行时校验 return new Proxy(this, { get(target, prop) { // 处理数字索引访问 if (typeof prop === 'string' && /^\d+$/.test(prop)) { const idx = Number(prop) return idx === 0 || idx === 1 ? target.#store[idx] : undefined } // 其他属性正常返回,保证instanceof等能力正常 return Reflect.get(target, prop) }, set(target, prop, value) { // 拦截数字索引赋值 if (typeof prop === 'string' && /^\d+$/.test(prop)) { const idx = Number(prop) if (idx !== 0 && idx !== 1) { // 可根据需求改为静默返回false不赋值,不抛出错误 throw new RangeError('Index can only be 0 or 1') } if (typeof value !== 'number') { throw new TypeError('Stored value must be number type') } target.#store[idx] = value return true } return Reflect.set(target, prop, value) } }) } }
效果验证
- 编译时类型限制
TS开发阶段直接禁止非法索引操作,无需等到运行时:
const t = new TupleWrapperClass(0, 3) t[0] = 5 // 正常操作 t[2] = 7 // 编译直接报错:类型“2”无法作为索引类型“AllowedIndex”使用
- 运行时拦截保护
就算绕开TS类型校验(如纯JS环境、使用any类型),也无法修改非法索引:
const t = new TupleWrapperClass(0, 3) as any console.log(t[0]) // 输出:0 console.log(t[1]) // 输出:3 console.log(t[2]) // 输出:undefined t[2] = 7 // 运行时抛出RangeError,赋值失败
- 保留运行时类型校验能力
原本的instanceof判断逻辑完全不受影响:
const t = new TupleWrapperClass(0,3) console.log(t instanceof TupleWrapperClass) // 输出:true
如果你不需要抛出错误提示,只需要静默禁止非法赋值,把set拦截器里的throw语句改为return false即可。
内容的提问来源于stack exchange,提问作者UndercoverNoob
相关产品推荐
相关产品推荐

