1

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.

1 Answer 1

2

You just need to check whether or not the inferred Rest is constrained by the extra type:

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.