'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

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

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. I know that in this example this constraint doesn't have much sense, but it is simpliest example that I find.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source