4

I wonder if there is any way of mapping ConstructorParameters<T> to an object where each key is the parameter name and the key is the type of the parameter.

What I mean is, given:

class User {
  public id: number;

  constructor(
      public readonly name: string,
      public readonly surname: string,
  ) {}

  get fullname(): string { ... }
  public isAdmin(): boolean { ... }
}

With ConstructorParameters<typeof User> I get the type [name: string, surname: string]. Maybe this can be mapped to the following type { name: string, surname: string }? Note that the type should omit: id, fullname & isAdmin as they are not present on the constructor.

I've seen https://stackoverflow.com/a/49062616 which is a really cool solution but it breaks with getters and public properties that are not present in the constructor.

2
  • Why not type UserMapped = { [P in keyof User]: User[P]; } ? Commented Apr 2, 2021 at 11:58
  • 1
    That returns everything public, including the methods, the getters and other public properties not defined in the constructor. In this case I only want to map the constructor parameters. Commented Apr 2, 2021 at 12:09

1 Answer 1

1

I don't think so. The "name" of the parameters of a function don't actually have any meaning outside the context of the function. For example, you can do this:

type FuncType = (foo: string) => void;

const MyFunc: FuncType = (bar) => {
  return bar;
}

The "name" of foo and bar don't match at all, but the order and type do, which is all that really matters. Probably similar to how you can destructure an array and give the items arbitrary names; the items in an array don't have names to begin with:

const array = [1, 2, 3];
const [one, two, three] = array;

About the closest you could probably get is to get the order and types of your constructor as an object, but I'm not sure how that would be useful:

type ConstructorParametersIndices<T extends new (...args: any) => any> =
  T extends new (...args: infer P) => any ? {[K in keyof P]: K} : never;

type A = ConstructorParameters<typeof User>;
// [name: string, surname: string]

type B = ConstructorParametersIndices<typeof User>;
// [name: "0", surname: "1"]

type C = {[P in B[number] as P]: A[P]};
/*  {
 *    0: string;
 *    1: string;
/*  }
Sign up to request clarification or add additional context in comments.

2 Comments

I see, as you mention, I have the impression that what I'm asking is not possible. Although, it's weird as from the VS Code hint looks like TS has knowledge of parameter name, that's why I though that maybe there was a way. When it's user defined tuple it's just the array of types…
@doup yeah it feels as if there should be some way to access the parameter "name" but I could not find one, it seems it's only there se some kind of hinting.

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.