打字稿。条件类型中错误的泛型参数约束

Typescript. Wrong generic parameter constraint in conditional 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'

它按我预期的那样工作。但是如果我想限制通用参数 - 它会失败

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;

我尝试使用 & - 它没有给出错误,但输出不是我所期望的

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

如何在条件类型中使用泛型类型约束来获得这样的输出

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'

P.S。我知道在这个例子中这个约束没有多大意义,但它是我找到的最简单的例子。

您只需要检查推断的 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