如何在TypeScript中限制泛型接口禁止使用unknown类型
如何限制TypeScript泛型接口禁止使用unknown作为参数
问题背景
我定义了如下泛型接口:
export interface IBaseDataResponse<T> extends ITraceData { attributes: T; id: string; type: string; relationships?: Record<string, string>; }
需要限制该接口不能接受unknown作为泛型参数,例如下面这种用法必须被禁止:
export interface IIncluded { included: IBaseDataResponse<unknown>[]; // 此处需限制unknown类型 }
尝试过的无效方案
我尝试通过类型约束实现,但出现了错误:
type NotAcceptable<T> = T extends unknown ? never : T interface IBaseDataResponse<T extends NotAcceptable<T>> { // 接口成员... }
当使用合法类型(比如string)时,TypeScript抛出错误:Type 'string' does not satisfy the constraint 'never'.ts(2344)
完整代码示例
interface ITraceData { type: string; } interface IRelationship { type: string; } interface IBaseDataResponse<T> extends ITraceData { attributes: T; id: string; type: string; relationships?: Record<string, IRelationship>; } interface IIncluded { included: IBaseDataResponse<unknown>[]; } class product { id: string = ''; name: string = ''; } const validResponse: IBaseDataResponse<product> = { attributes: { id:'1', name: 'alireza' }, id: 'string', type: 'string', }; // 此处应被限制,禁止使用IBaseDataResponse<unknown> const InValidResponse: IBaseDataResponse<unknown> = { attributes: { id:'1', name: 'alireza' }, id: 'string', type: 'string', };
解决方案
要实现禁止unknown作为泛型参数,需要利用unknown的特殊性——只有unknown自身能在严格条件下匹配unknown extends T,可以通过以下两种方式实现:
方式一:使用类型别名
type NotUnknown<T> = T extends unknown ? unknown extends T ? never : T : T; interface IBaseDataResponse<T extends NotUnknown<T>> extends ITraceData { attributes: T; id: string; type: string; relationships?: Record<string, IRelationship>; }
方式二:直接内联约束
interface IBaseDataResponse<T extends (unknown extends T ? never : T)> extends ITraceData { attributes: T; id: string; type: string; relationships?: Record<string, IRelationship>; }
原理说明
- 当传入的泛型参数
T是unknown时,unknown extends T成立,约束会返回never,而unknown无法满足extends never的条件,因此直接报错。 - 当传入其他类型(如
string、自定义类product)时,unknown extends T不成立,约束返回T自身,类型检查正常通过。
测试验证:
- 合法用法
IBaseDataResponse<product>:通过类型检查。 - 非法用法
IBaseDataResponse<unknown>:抛出错误Type 'unknown' does not satisfy the constraint 'NotUnknown<unknown>'.ts(2344),达到预期限制效果。
内容的提问来源于stack exchange,提问作者Alireza Ahmadi
相关产品推荐
相关产品推荐

