在TypeScript中不使用泛型,能否让函数输出类型作为另一函数输入类型?
不用泛型能否实现两个函数的输入输出类型关联?
我们知道用泛型可以轻松声明这样的类型:一个对象里的function1返回类型T,function2的参数类型就是这个T,代码如下:
type ExampleType<T> = { function1: (param: number) => T; function2: (param: T) => number; }
那不用泛型的话,能不能达到同样的类型约束效果?
你尝试的写法的问题
你之前试过这样声明:
type ExampleType = { function1: (param: number) => any; function2: (param: ReturnType<ExampleType['function1']>) => number; }
但这里用any会完全关闭类型检查,导致像下面这样明显不匹配的代码也能通过编译:
const example1: ExampleType = { function1: (param: number): string => { // ... }, function2: (param: number): number => { // ... }, }
这里function1返回string,但function2接收number,类型完全不匹配却没被检测出来,就是因为any的存在——ReturnType<ExampleType['function1']>会被解析成any,所以function2的参数类型实际是any,自然能接受任何类型。
为什么不用泛型做不到?
TypeScript的类型系统里,要让两个属性的类型产生关联,需要一个可复用的类型变量来绑定它们的关系,而泛型就是用来提供这种类型变量的。如果不用泛型,我们没法声明一个“能动态跟随具体对象实例变化”的类型关联——普通类型别名是静态的,没法针对每个实例单独约束function1和function2的类型关系。
有没有替代方案?
如果一定要避免显式泛型,你可以用联合类型+条件类型来模拟,但这种方式非常受限,只能覆盖你预先定义好的几种类型组合,比如:
type ExampleType = | { function1: (param: number) => string; function2: (param: string) => number } | { function1: (param: number) => number; function2: (param: number) => number } | { function1: (param: number) => boolean; function2: (param: boolean) => number };
但这种写法完全不灵活,没法支持任意类型的关联,和泛型的效果差远了。
所以结论是:如果要实现任意类型的动态关联,泛型是唯一可行的方案,不用泛型要么会丢失类型检查,要么只能做有限的静态类型覆盖。
内容的提问来源于stack exchange,提问作者Procyon
相关产品推荐
相关产品推荐

