为何此TypeScript示例中`value`未自动收窄为`number`类型?
为什么TypeScript泛型函数里
value没自动收窄成number? 这是TypeScript泛型类型系统的一个局限——当你在泛型函数里判断property === Property.Height时,它没办法把泛型参数T精准锁定为Property.Height,自然也就没法同步把value的类型从Data[T]收窄成number。
毕竟T的定义是T extends Property,它代表的是Property枚举的任意子集(可能是单个值,也可能是多个值的联合)。哪怕你通过条件判断确定了当前property是Height,TypeScript也不会把这个判断结果关联到泛型参数T的约束上,所以value的类型依然保持为Data[T],不会自动变成number。
几种解决办法
1. 手动用类型断言指定
如果你能确定当前分支下value就是number,可以直接用类型断言强制指定:
if (property === Property.Height) { const numValue = value as number; // 现在numValue是number类型,能正常调用number的方法 }
2. 改用联合类型的参数对,放弃泛型
把参数改成“属性+值”的联合类型对,让TypeScript能通过类型守卫自动收窄:
type PropertyValuePair = | [property: Property.Height, value: number] | [property: Property.Name, value: string] | [property: Property.DateOfBirth, value: Date]; function example(...[property, value]: PropertyValuePair) { if (property === Property.Height) { // value自动变成number类型 console.log(value.toFixed(2)); } }
3. 自定义类型守卫关联参数类型
写一个自定义类型守卫函数,明确把property和value的类型绑定起来:
function isHeightPair<T extends Property>( value: Data[T], property: T ): value is Data[Property.Height] { return property === Property.Height; } function example<T extends Property>(value: Data[T], property: T) { if (isHeightPair(value, property)) { // value被自动收窄为number console.log(value.toFixed(2)); } }
内容的提问来源于stack exchange,提问作者Viriato
相关产品推荐
相关产品推荐

