如何强制TypeScript函数类型别名的返回类型做严格校验
校验行为不一致的原因
TypeScript 的多余属性校验仅对直接赋值给明确类型的对象字面量生效,两种写法的校验逻辑差异如下:
- 第一种写法中,对象字面量并没有直接赋值给
MyType类型的位置:TypeScript 会先推断箭头函数的返回类型为包含asdfasdf属性的扩展结构,再判断该结构是否兼容MyType。由于 TypeScript 默认使用结构类型系统,只要返回值包含MyType要求的所有必填属性就会判定兼容,不会校验多余属性,因此不会报错。 - 第二种写法中,你直接给函数显式声明了返回类型为
MyType,return 后的对象字面量是直接赋值给MyType类型的返回位置,会触发严格的多余属性校验,因此多余字段会被检测到并抛出错误。
让函数类型别名也触发严格多余属性校验的方法
你可以选择以下任意一种方案实现:
方案1:给箭头函数显式标注返回类型
直接在箭头函数的参数列表后声明返回类型,触发多余属性校验:
const foo: ReturnsMyType = (): MyType => { return { id: '', strings: [], asdfasdf: '' // 此处会正常抛出多余属性错误 } }
方案2:返回值使用satisfies运算符(推荐,TS 4.9+支持)
在返回的对象字面量后加satisfies MyType,强制触发多余属性校验,不需要修改函数类型定义:
const foo: ReturnsMyType = () => { return { id: '', strings: [], asdfasdf: '' // 此处会抛出错误 } satisfies MyType }
方案3:定义严格匹配的函数类型别名
自定义Exact工具类型,约束返回值必须和目标类型完全匹配,不能有多余属性:
// 定义Exact工具类型,要求两个类型结构完全一致 type Exact<T, U extends T> = U extends T ? T extends U ? U : never : never; // 定义严格校验返回值的函数类型 type StrictReturnsMyType = <U extends MyType>() => Exact<MyType, U>; const foo: StrictReturnsMyType = () => { return { id: '', strings: [], asdfasdf: '' // 此处会抛出类型不兼容错误 } }
内容的提问来源于stack exchange,提问作者jered
相关产品推荐
相关产品推荐

