如何让TypeScript函数仅接受特定类型并触发类型不匹配错误提示
实现TypeScript接口与变量的严格类型匹配
TypeScript默认采用结构类型系统(鸭子类型),只要对象包含接口要求的所有属性,即使存在额外属性也能通过类型检查。要让doSome函数对包含未声明属性的pos报错,可通过以下几种方式实现严格类型校验:
方法1:使用Exact工具类型
定义一个Exact工具类型,强制传入的类型与接口完全一致,不允许额外属性:
// 定义Exact工具类型,确保T和U完全匹配 type Exact<T, U> = T extends U ? U extends T ? T : never : never; interface Pos { x: number; y: number; } // 用泛型+Exact限制参数类型 function doSome<T extends Pos>(pos: Exact<T, Pos>) { return pos.x + pos.y; } let pos = { x: 1, y: 2, z: 3, }; // 此处会报错:类型 '{ x: number; y: number; z: number; }' 不能赋值给类型 'Exact<{ x: number; y: number; z: number; }, Pos>' let p = doSome(pos);
方法2:通过交叉类型禁止额外属性
构造一个包含never类型索引签名的交叉类型,让任何额外属性都与never冲突:
interface Pos { x: number; y: number; } // 交叉Pos与索引签名,禁止额外属性 type StrictPos = Pos & { [key: string]: never }; function doSome(pos: StrictPos) { return pos.x + pos.y; } let pos = { x: 1, y: 2, z: 3, }; // 此处报错:类型 '{ x: number; y: number; z: number; }' 不能赋值给类型 'StrictPos' // 原因:属性'z'的类型'number'与'never'不兼容 let p = doSome(pos);
方法3:直接声明变量为接口类型
在定义pos变量时就指定其类型为Pos,这样在变量初始化阶段就会报错,更早拦截问题:
interface Pos { x: number; y: number; } function doSome(pos: Pos) { return pos.x + pos.y; } // 此处直接报错:对象文字可以只指定已知属性,'z'不在类型'Pos'中 let pos: Pos = { x: 1, y: 2, z: 3, }; let p = doSome(pos);
内容的提问来源于stack exchange,提问作者Ólavur Nón
相关产品推荐
相关产品推荐

