【发布时间】:2022-01-11 05:58:27
【问题描述】:
在这个例子中:
type MyType = 'val1' | 'val2' | 'val3';
const variable = 'val1' as MyType;
const val2 = 'val2';
const val3 = 'val3';
declare function test<U extends MyType>(...args: U[]): void;
test(val2, val3); // U successfully resolves to "val3" | "val2"
declare function test2<T, U extends T>(value: T | undefined, ...values: U[]): void;
test2(variable, val2, val3); // U gets widened to "val1" | "val2" | "val3"
在test 和test2、U extends MyType 中。
然后我希望test2 能够将U 解析为"val3" | "val2",就像它在test 中所做的那样,但事实并非如此。
这是为什么呢?
【问题讨论】:
-
T是MyType和U扩展T然后U扩展MyType。 -
U在这两种情况下都扩展了MyType那么为什么它的行为不同呢? -
@GuerricP 在 test1 中,
val2的类型为"val2"和val3的类型为"val3"。在 test2 中,variable的类型为"val1" | "val2" | "val3"。所以在 test1 中,U的类型可以通过val2和val3的类型来缩小范围。但是在 test2 中,T的类型(以及通过代理还U)被强制与variable的类型一样宽,即"val1" | "val2" | "val3" -
@Olian04 但是在
test2中,T的类型被强制与变量的类型一样宽因为约束是@987654353,所以不应该这样做@ 所以它 U 可能是一个子类型。'val1' | 'val2'实际上扩展了'val1' | 'val2' | 'val3' -
@GuerricP 可能不会。以我的经验,TS 经常做这种事情。 TS团队让TS时不时偷工减料。特别是如果它可以检测到生成的类型不会在类型系统的其他地方使用。我认为 TS 认为
"val1" | "val2" | "val3"类型对于参数列表来说已经足够好了。但是,如果预计会返回类型U,则需要花费更多时间来解析其实际类型。
标签: typescript generics