TypeScript泛型默认类型选择:unknown vs any
为泛型接口设置默认类型,实现无需指定泛型参数的使用场景
你可以通过为泛型参数设置默认类型来实现需求,TypeScript支持为泛型类型参数定义默认值,当省略泛型参数时,会自动使用这个默认类型。
可行方案
直接在泛型参数后添加= 默认类型即可修改接口:
// 以 unknown 为默认类型 export interface MyStructure<Data = unknown> { id: string; data: Data; } // 或者以 any 为默认类型 export interface MyStructure<Data = any> { id: string; data: Data; }
修改后,就能像这样省略泛型参数使用:
function printId(obj: MyStructure): void { console.log(obj.id); }
unknown 和 any 作为默认类型的核心区别
1. 用 unknown 作为默认类型:类型安全优先
unknown是TypeScript中最严格的顶级类型,所有类型都能赋值给它,但在没有明确的类型断言或类型缩小操作前,不能对unknown类型的值做任何操作。- 比如在
printId里尝试直接访问obj.data的属性,TypeScript会直接抛出编译错误,避免写出运行时可能出错的代码:
function printId(obj: MyStructure): void { console.log(obj.id); // 正常运行 // console.log(obj.data.name); // 编译报错:无法访问unknown类型的属性 }
- 适合这类不需要操作
data属性的场景,既能简化使用,又能保留类型检查的安全性。
2. 用 any 作为默认类型:完全放弃类型检查
any会彻底关闭TypeScript的类型校验,可以对obj.data执行任意操作,不管它实际是什么类型,编译阶段都不会报错,但会埋下运行时错误的隐患。- 比如下面的代码编译时不会报错,但如果传入的
obj.data没有name属性,运行时就会抛出异常:
function printId(obj: MyStructure): void { console.log(obj.id); // 正常运行 console.log(obj.data.name); // 编译不报错,但运行时可能出错 }
- 仅适合需要完全灵活处理
data,且能接受类型风险的场景,一般不推荐在大多数业务代码中使用。
总结
如果只是像printId这样不需要操作data的场景,优先选择unknown作为默认类型,既能简化使用,又能保留TypeScript的类型安全;只有在特殊需求下,才考虑使用any。
内容的提问来源于stack exchange,提问作者Francesco Borzi
相关产品推荐
相关产品推荐

