2

Need to generate array of types from object type:

type T = {
    a: number | string;
    b: string | number;
    c: number;
    d: boolean;
};

Expect:

[number | string, string | number, number, boolean]

Want to use as a type to describe spread arguments in a function:

function fun(...args: values of T) {
    const [a, b, c, d] = args;
}

fun("a", "b", 8, true);

3 Answers 3

2

I don't think you can, because the array of args is of indeterminate order. If you try to spread the args into an array and try to type it as Array<T[keyof T]>, you will cause TypeScript to blend all the types together, since it cannot deterministically narrow the type on individual array items. See it on the playground.

function fun(...args: Array<T[keyof T]>) {
    const [a, b, c, d] = args;
}

Blending of types

If you look at the inferred types, this essential evaluates to args having a type of <number | string | boolean>[].

The only way out is if you can inform TypeScript that there is a fixed number of arguments, by passing in all 4 arguments as a single object. See it on the playground.

function fun({ ...args }: T) {
    const { a, b, c, d } = args;
}

fun({
   a: 'a',
   b: 'b',
   c: 8,
   d: true 
});

And upon deconstructing the args object, you will receive the correct typings:

Deconstructed typings

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

Comments

0

Object properties in javascript are not guaranteed to be ordered, so typescript can't know how named properties map to ordered values.

How would you expect this example to work? What would the argument order be? It's pretty unclear.

interface HasID {
  id: number
}

interface Message extends HasID {
  message: string
}

I think the best you'll get is a less dynamic approach, such as pulling the property out explicitly for each argument:

type T = {
    a: number | string;
    b: string | number;
    c: number;
    d: boolean;
};

function fun(a: T['a'], b: T['b'], c: T['c'], d: T['d']) {
    var obj: T = { a, b, c, d }
}

fun("a", "b", 8, true);

Comments

-1

You can try using Object.values(objectName) to convert your object to array.

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.