如何让TypeScript在判别联合赋值多余属性时抛出错误?
问题描述
我有以下TypeScript类型定义:
interface BaseHeaderColumn<T> { accessorKey: keyof T; label: string; } interface RenderableHeaderColumn<T> { accessorKey: string; label: string; renderCell: (originData: T) => any; } type HeaderColumnType<T> = BaseHeaderColumn<T> | RenderableHeaderColumn<T>; interface DataType { name: string; age: number; address: string; }
之后我会定义这样的列配置:
const HeaderColumns: HeaderColumnType<DataType>[] = [ { accessorKey: "age", label: "Age", renderCell: () => "" }, { accessorKey: "no", label: "Number", renderCell: (value) => "" } ]
我的需求是:当accessorKey是T(比如这里的DataType)的键时,TypeScript要禁止传入renderCell方法。请问这个需求能实现吗?
实现方案
可以通过调整联合类型的定义,利用TypeScript的条件类型和可辨识联合特性实现该约束。核心思路是让两种列类型的accessorKey形成互斥判断,同时在accessorKey属于keyof T时,将renderCell设为never类型(即不允许存在该属性)。
调整后的类型定义如下:
type HeaderColumnType<T> = | { accessorKey: keyof T; label: string; renderCell?: never; // 明确禁止传入该属性 } | { accessorKey: Exclude<string, keyof T>; label: string; renderCell: (originData: T) => any; }; interface DataType { name: string; age: number; address: string; }
此时测试原配置会得到预期约束:
- 第一个对象
accessorKey: "age"属于DataType的键,传入renderCell会直接触发TypeScript错误,符合需求。 - 第二个对象
accessorKey: "no"不属于DataType的键,必须传入renderCell(省略会报错),完全符合预期。
原理说明
Exclude<string, keyof T>:排除string类型中属于T的键的部分,确保第二种类型的accessorKey只能是T中不存在的字符串。renderCell?: never:never类型表示该属性不能有任何有效值,即使是可选属性,传入任何值都会触发类型错误,从而达到禁止传入的效果。
内容的提问来源于stack exchange,提问作者haovo
相关产品推荐
相关产品推荐

