Bug报告
🔎 搜索词
generic function union intersection type optional property
🕗 版本与回归信息
- 在版本3.6.0-dev.20190723和版本3.6.0-dev.20190724之间发生了变化
⏯ Playground链接
带有相关代码的Playground链接
💻 代码
type A = ({ a: any } | { b: any }) & { c?: any };
declare function testA<Param extends A>(param: Param & A): Param;
declare const s1: A;
const a1 = testA(s1);
/**
* Argument of type 'A' is not assignable to parameter of type '{ b: any; } & A'.
* Type '{ a: any; } & { c?: any; }' is not assignable to type '{ b: any; } & A'.
* Type '{ a: any; } & { c?: any; }' is not assignable to type '{ b: any; } & { a: any; } & { c?: any; }'.
* Property 'b' is missing in type '{ a: any; } & { c?: any; }' but required in type '{ b: any; }'.(2345)
*/
type B = ({ a: any } | { b: any }) & { c: any };
declare const s2: B;
const a2 = testA(s2); // Type of result is A but must be B
🙁 实际行为
行const a1 = testA(s1);
出现错误:
Argument of type 'A' is not assignable to parameter of type '{ b: any; } & A'.
Type '{ a: any; } & { c?: any; }' is not assignable to type '{ b: any; } & A'.
Type '{ a: any; } & { c?: any; }' is not assignable to type '{ b: any; } & { a: any; } & { c?: any; }'.
Property 'b' is missing in type '{ a: any; } & { c?: any; }' but required in type '{ b: any; }'.(2345)
在行const a2 = testA(s2);
中,TypeScript编译器推断常量a a2
的类型为A
。
🙂 预期行为
变量s1
具有类型A
,这意味着function testA<Param extends A>(param: Param & A): Param
接受s1
。参数类型Param
示例化为A
。
常量a2
具有类型B
,因为参数s2
具有类型B
。
这是正常的行为,直到version 3.6.0-dev.20190723。从那时起,它导致了错误。
4条答案
按热度按时间k97glaaz1#
另外,值得注意的是,当编译器在错误信息中将
{ b: any } & A
显示为{ b: any; } & { a: any; } & { c?: any; }
时,它得出了错误的结论。lstz6jyr2#
和
有什么意图?
cgfeq70w3#
这是一个简化了实际代码中暴露bug的例子。这种模式在类型没有正确缩小的设计限制的通用函数中很有用:
可以通过向
animal
参数的类型添加& Animal
来修复它:链接到Playground
如果我们使
Animal
类型更复杂:它仍然有效(链接到Playground)。
当我们决定让属性
domesticated
是可选的时候,结果发现代码是错误的:链接到Playground
现在,当版本4.3.2带有改进的泛型上下文缩小功能已经发布时,它变得不那么实际了。现在我们可以跳过
& Animal
部分。但是这个bug是一个bug。它可能会影响遗留代码,或者是更大问题的一个破损部分。
avkwfej44#
我找到了这个模式仍然有用的用例:
链接到Playground
在TypeScript 3.3.3333中运行良好:链接