简体   繁体   English

Typescript. 条件类型中错误的泛型参数约束

[英]Typescript. Wrong generic parameter constraint in conditional type

Consider such type考虑这样的类型

type Last<TProps> =
TProps extends [infer TProp]
  ? TProp
  : TProps extends [infer TProp, ... infer Rest] & PropertyKey[]
    ? Last<Rest>
    : never;

export type L0 = Last<['a']>;           // 'a'
export type L1 = Last<['a', 'b']>;      // 'b'
export type L2 = Last<['a', 'b', 'c']>; // 'c'

It work as I expected.它按我的预期工作。 But if I want to restrict generic parameter - it fails但是如果我想限制通用参数 - 它会失败

type Last<TProps extends PropertyKey[]> =
TProps extends [infer TProp]
  ? TProp
  : TProps extends [infer TProp, ... infer Rest]
    ? Last<Rest> // error. 'Rest' does not satisfy the constraint 'PropertyKey[]'
    : never;

I tried to use & - it give no error, but output is not what i expected我尝试使用 & - 它没有给出任何错误,但 output 不是我所期望的

type Last<TProps extends PropertyKey[]> =
TProps extends [infer TProp]
  ? TProp
  : TProps extends [infer TProp, ... infer Rest]
    ? Last<Rest & PropertyKey[]> // no error
    : never;

export type L0 = Last<['a']>;           // 'a'
export type L1 = Last<['a', 'b']>;      // string | number | symbol
export type L2 = Last<['a', 'b', 'c']>; // never

How I can use generic type constraint in conditional type to obtain such output我如何在条件类型中使用泛型类型约束来获得这样的 output

type Last<TProps extends PropertyKey[]> = ????

export type L0 = Last<['a']>;           // 'a'
export type L1 = Last<['a', 'b']>;      // 'b'
export type L2 = Last<['a', 'b', 'c']>; // 'c'

PS I know that in this example this constraint doesn't have much sense, but it is simpliest example that I find. PS 我知道在这个例子中这个约束没有多大意义,但它是我发现的最简单的例子。

You just need to check whether or not the inferred Rest is constrained by the extra type:您只需要检查推断的Rest是否受额外类型的约束:

type Last<TProps extends PropertyKey[]> =
TProps extends [infer TProp]
  ? TProp
  : TProps extends [infer TProp, ... infer Rest] & PropertyKey[]
    ? Rest extends PropertyKey[]
      ? Last<Rest>
      : never
    : never;

export type L0 = Last<['a']>;
export type L1 = Last<['a', 'b']>;
export type L2 = Last<['a', 'b', 'c']>;

TS Playground TS游乐场

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

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