ankobus
ankobus

Reputation: 21

Convert object type to array of types

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);

Upvotes: 2

Views: 310

Answers (3)

Alex Wayne
Alex Wayne

Reputation: 187272

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);

Upvotes: 0

Terry
Terry

Reputation: 66228

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

Upvotes: 2

Madara Uchiha
Madara Uchiha

Reputation: 37

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

Upvotes: -1

Related Questions