TypeScript中export function与export type定义函数类型有何区别?
两种TypeScript模块导出写法的区别
核心本质差异
- 第一种
export function声明
该写法同时在类型空间和值空间注册了ModuleFactory实体:- 作为值:TS会认为
@my/customs包下存在名为ModuleFactory的可调用函数值,你可以直接引入调用、或者实现该导出值,符合TS的值校验规则 - 作为类型:该函数声明自带对应的函数类型,你也可以把它当作类型来做变量约束
代码示例:
- 作为值:TS会认为
// 可以正常引入作为值使用 import { ModuleFactory } from '@my/customs' ModuleFactory({}) // 无报错
- 第二种
export type声明
该写法仅在类型空间注册了ModuleFactory类型别名,它本质是对(environment: any) => any这个函数签名的命名,完全不涉及运行时值的声明:- 仅能用于类型标注、类型运算场景,不能当作实际存在的值进行调用、赋值、实现,否则就会抛出TS2693错误
报错原因说明
你实现ModuleFactory(environment){..}的操作本质是创建一个同名的值,第二种写法只声明了类型,没有告知TS存在对应的可导出值,因此TS判定你将纯类型实体当作值使用,触发错误。
第二种写法的适用场景
export type导出的函数类型别名适用于仅需要做类型约束的场景:
- 复用函数类型约束自定义实现
import type { ModuleFactory } from '@my/customs' // 约束自己实现的工厂函数符合指定的入参、返回值规则 const myCustomFactory: ModuleFactory = (env) => { // 自定义实现逻辑 return {} }
- 简化其他类型定义的编写
当其他类型需要引用该函数签名时,直接用别名即可,无需重复编写冗长的函数签名:
type PluginConfig = { name: string // 直接引用类型别名,不用再写 (env:any)=>any factory: ModuleFactory }
- 纯类型包导出类型规范
如果你的类型声明包仅提供接口规范,具体的实现由接入方自行完成,就可以用这种方式导出类型给接入方做校验。
内容的提问来源于stack exchange,提问作者Roman Pokrovskij
相关产品推荐
相关产品推荐

