为何number的子类型无法被当作number类型使用?
TypeScript中number子类型无法直接当作number使用的原因分析
先看你给出的代码示例:
async function someFunction<T extends number>(fn: () => Promise<T>): Promise<T> { const result: number = await fn(); return result; // 报错 } async function otherFunction(fn: () => number): Promise<number> { const result: number = await fn(); return result; // 正常运行 }
问题核心原因
泛型函数someFunction里的T是number的子类型——比如具体的数字字面量类型1、2,或是0 | 1这种联合类型,它们的取值范围比宽泛的number类型窄得多。
当你把await fn()得到的T类型值赋值给number类型的result时,TypeScript会自动把result的类型拓宽成通用的number。但函数声明的返回类型是更具体的T,你不能把一个“范围更大的类型”赋值给“范围更小的子类型”,这就像你没法把一个普通number变量直接赋值给类型为1的变量一样——number可能是3、4这类不符合1约束的值。
反观otherFunction,它的返回类型本身就是number,result的类型和返回要求完全匹配,所以不会报错。
解决办法
- 直接返回异步结果,跳过中间变量:
async function someFunction<T extends number>(fn: () => Promise<T>): Promise<T> { return await fn(); }
- 如果需要保留中间变量,保持变量类型为
T而非number:
async function someFunction<T extends number>(fn: () => Promise<T>): Promise<T> { const result: T = await fn(); return result; }
内容的提问来源于stack exchange,提问作者Paulo Fernando
相关产品推荐
相关产品推荐

