1

I have these three helpers defined:

export type IdType = PropertyKey;
export type Identifiable<T> = T & {id: IdType};
export type IdGetter<T> = (x: Identifiable<T>) => IdType;

I would like to be able to type generic methods using the IdGetter generic, like (this doesn't work, but that's the sort of thing I would like to be able to do):

export const getId<T>: IdGetter<T> = x => x.id

But instead I have to write:

export const getId = <T>(x: Identifiable<T>): IdType => x.id;

It's not a big deal, I can still do things like that and have no type errors:

const f = <U, F extends IdGetter<U>>(getter: F) => (x: Identifiable<U>): IdType => getter(x);
f(getId);

But defining the types of these getters is redundant.

Is there a clean way to do what I'm looking for? I'm trying to get better at using generics.

1
  • TS is unfortunately not expressive enough to represent the relationship between those two function types in the type level. You have to do what you're doing, even if it's redundant. See the linked questions and answers above for more information. Commented Sep 15, 2024 at 14:08

1 Answer 1

0

The approach you’re using is already clean and idiomatic for TypeScript, especially with generic functions. If the goal is to avoid redundant type definitions, the below approach is likely the cleanest without losing type safety.

You can define getId with a direct assertion that its type matches IdGetter with the Inline Type Assertion approach:

export const getId: <T>(x: Identifiable<T>) => IdType = x => x.id;

Hope this helps!

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.