如何让TypeScript在返回类型含多余属性时抛出错误?
问题分析与解决
为什么没报错?
TypeScript采用结构类型系统,只要对象包含目标类型的所有必填属性,就会被判定为类型兼容,额外属性不会触发错误。尤其是在函数返回值、联合类型参数这类场景下,TypeScript不会启用严格的额外属性检查,所以你添加abc属性时未收到报错提示。
解决方案
这里提供三种实用的解决方法:
方法1:使用satisfies关键字(TypeScript 4.9+)
直接在props返回的字面量后追加satisfies List<NewT>,强制TypeScript检查字面量是否完全匹配目标类型,禁止额外属性:
apiProps<NewT>({ scope: ScopeType.LIST, props: (_) => ({ test: "1444", limit:12, abc:"abc" // 此处会报错:类型"{ test: string; limit: number; abc: string; }"不能赋给类型"List<NewT>" }) satisfies List<NewT>, api: () => {}, type: "asd" })
方法2:自定义精确类型约束
如果你的TypeScript版本低于4.9,可以自定义一个精确类型工具,强制禁止额外属性:
// 定义精确类型工具,限制仅允许目标类型的属性存在 type Exact<T> = T & Record<Exclude<keyof any, keyof T>, never>; // 修改List类型为精确类型 type List<T> = Exact<T & { limit: number; }>; // 此时原代码中的abc属性会触发错误 apiProps<NewT>({ scope: ScopeType.LIST, props: (_) => ({ test: "1444", limit:12, abc:"abc" // 报错:类型"string"不能赋给类型"never" }), api: () => {}, type: "asd" })
方法3:优化泛型参数的类型推断
调整apiProps的泛型定义,让TypeScript更精确地匹配分支类型,触发字面量检查:
const apiProps = <T extends unknown>( a: | (GetApiPropsList<T> & { scope: ScopeType.LIST }) | (GetApiPropsGeneric<T> & { scope: ScopeType.GENERIC }) ) => { console.log("as") } // 此时传入abc会报错,TypeScript会严格匹配GetApiPropsList<T>的props返回类型 apiProps<NewT>({ scope: ScopeType.LIST, props: (_) => ({ test: "1444", limit:12, abc:"abc" // 报错:类型"{ test: string; limit: number; abc: string; }"不能赋给类型"List<NewT>" }), api: () => {}, type: "asd" })
内容的提问来源于stack exchange,提问作者LMG
相关产品推荐
相关产品推荐

