TypeScript自定义类/接口能否使用内置预定义名称?冲突是否会报错?
TypeScript 自定义类型命名与内置预定义名称冲突问题解答
能否使用内置预定义名称命名自定义类/接口
TypeScript 本身没有禁止使用内置预定义名称定义自定义类、接口或类型别名,最终是否合法取决于你声明的作用域:
- 如果你在模块作用域(即文件存在
import/export语句)下声明,完全合法。模块内的声明默认是局部作用域,会覆盖全局同名标识符的解析,不会和全局内置声明产生默认冲突。 - 如果你在全局作用域(即文件无
import/export语句,属于全局脚本)下声明,是否合法取决于声明类型是否支持和内置声明合并:如果是同名interface可以合法合并,要是声明类型和内置不兼容(比如内置是类型别名,你声明成类)就会直接报错。
会触发错误的冲突场景
以下是几种常见的冲突报错场景:
- 全局作用域下声明类型不兼容
内置预定义的RequestInfo是类型别名,类型别名无法和类声明合并,如果你直接在全局脚本里写class RequestInfo {},会直接抛出TS2300: Duplicate identifier 'RequestInfo'的重复标识符错误。 - 声明合并时结构不兼容
如果全局声明同名interface,但属性定义和内置冲突也会报错。比如内置Request接口的url属性是string类型,你全局声明interface Request { url: number },合并时就会因为属性类型冲突抛出错误。 - 局部声明覆盖导致的类型不匹配
如果你在模块内声明了自定义的RequestInfo类,后续需要用到全局内置RequestInfo类型时如果没加globalThis.前缀,就会误用自定义类型,产生类型不匹配错误。比如内置RequestInfo是Request | string的联合类型,你自定义的类不包含string类型,把字符串赋值给RequestInfo类型的变量就会抛出类型错误。
针对RequestInfo示例的具体说明
你完全可以创建名为RequestInfo的自定义类:
- 如果是在模块文件中创建,没有任何默认冲突,模块内使用
RequestInfo时默认指向你定义的类。 - 如果要在全局脚本中创建,会直接触发重复标识符错误,非必要不建议这么做。
实用建议
非特殊需求不推荐使用内置预定义名称命名自定义类型,避免不必要的类型混淆,尤其是多人协作项目中很容易导致其他开发者误用。如果确实需要使用,建议放在模块作用域内,或者给自定义名称加前后缀做区分,比如CustomRequestInfo。
内容的提问来源于stack exchange,提问作者Nikitha
相关产品推荐
相关产品推荐

