为何TypeScript在函数内部会"遗忘"泛型约束?
TypeScript泛型函数内部类型收窄问题
以下是问题的代码示例:
type Shape = 'square' | 'circle'; type Params<S extends Shape> = S extends 'square' ? { side: number } : { radius: number }; function getArea<S extends Shape>(shape: S, params: Params<S>) { switch (shape) { // *必须手动断言Params类型*,否则TS会认为params可能是{ side: number }或{ radius: number } case 'square': return Math.pow((params as Params<'square'>).side, 2); case 'circle': return (params as Params<'circle'>).radius * Math.PI; // *必须添加默认分支*,否则TS报错说存在未返回值的代码路径 default: return -1; } } // 但函数调用时TS能正确应用泛型约束,以下代码会触发正确的类型错误: getArea('square', { radius: 1 }) // TS提示:{ radius: 1 }无法赋值给{ side: number }
核心问题点
- 函数外部:TS能正确识别
shape必须为Shape类型,params必须匹配对应Shape的Params类型,非法调用会直接触发类型错误。 - 函数内部:TS无法通过
switch-case收窄shape的具体类型,也就无法自动关联params的对应类型,必须手动添加类型断言。 - 额外现象:即使
Shape是明确的有限联合类型,TS仍要求添加默认分支。推测是泛型<S extends Shape>使得S的类型范围并非严格等同于Shape联合类型,但外部调用时又能正确限制shape只能是Shape的成员。
内容的提问来源于stack exchange,提问作者David Herskovics
相关产品推荐
相关产品推荐

