简体   繁体   English

打字稿正在改变推断的类型

[英]Typescript is changing type that was inferred

I'm working on a complex generic and one of its parts is not working as expected:我正在研究一个复杂的泛型,它的一个部分没有按预期工作:

// T and U are changed 
type Type<T> = T extends Array<infer U> ? U extends object ? Array<U> : T : never;

Inffered type U become UnionMember1[] | UnionMember2[]推断类型U成为UnionMember1[] | UnionMember2[] UnionMember1[] | UnionMember2[] instead of expected (UnionMember1 | UnionMember2)[] : UnionMember1[] | UnionMember2[]而不是预期的(UnionMember1 | UnionMember2)[]

type Z = { a: string };
type Y = { b: number }

const complex: Array<Z | Y> = [{ a: '1'}, { b: 1 }];

// Type '({ a: string; } | { b: number; })[]' is not assignable to type 'Z[] | Y[]'.
const complexChild: Type<typeof complex> = [{ a: '1'}, { b: 1 }]; 

Another curious part (but can be completely covered by fixing the case with inferred type) is that T has changed:另一个奇怪的部分(但可以通过使用推断类型修复案例来完全覆盖)是T发生了变化:

const primitive: Array<string | number> = ['1', 1];

// Type '(string | number)[]' is not assignable to type '(string[] & (string | number)[]) | (number[] & (string | number)[])'.
const primitiveChild: Type<typeof primitive> = ['1', 1];

Any suggstions how to fix that?任何建议如何解决? Thanks!谢谢!

Playground link 游乐场链接

The behaviour you are seeing here can be explained by the existence of distributive conditional types .您在此处看到的行为可以通过分布条件类型的存在来解释。

When you write U extends object ? ... : ...当你写U extends object ? ... : ... U extends object ? ... : ... in the generic type Type and U resolves to a union, each member of the resulting union will be distributed individually to the next statement (in this case Array<U> ). U extends object ? ... : ...在泛型类型TypeU中解析为一个联合,生成的联合的每个成员将单独分发到下一个语句(在本例中为Array<U> )​​。

You can stop the distibution by wrapping U and object inside a tuple.您可以通过将Uobject包装在一个元组中来停止分发。

type Type<T> = T extends Array<infer U> 
  ? [U] extends [object] 
    ? Array<U> 
    : T 
  : never;

Playground 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM