2

Is it possible to define this function

function magic(...propertyNames:string[]): { ????? : any }
{
....
}

In such away that returned type would have properties as listed in propetyNames?

For example:

type ResultType = {alpha:any, bravo:any};

let res = magic('alpha', 'bravo'); // res is compatible with ResultType

1 Answer 1

4

Here is a possible solution that can make magic happen:

declare function magic<T extends string[]>(
  ...propertyNames: T
): Record<T[number], any>;

const result = magic("alpha", "bravo");

type ResultType = typeof result; // {alpha: any; bravo: any;}

Testing of ResultType:

const t1: ResultType = {
  alpha: "foo",
  bravo: 42,
  wannaBe: 3 // error (OK)
};

You could then further restrict the any type in Record<T[number] any> with an additional type parameter, as any doesn't provide any useful typing.

declare function magic<T extends string[], R>(
  ...propertyNames: T
): Record<T[number], R>;

Some explanation

  • T[number] gives us all item values as union type. E.g.
type T = ["alpha", "bravo"]
type TItems = T[number] // "alpha" | "bravo"
  • Record makes sure, that we have all item values "alpha" | "bravo" as property keys.
  • The tuple type can be inferred with help of generic rest parameters.

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.