Reputation: 21
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
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
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;
}
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:
Upvotes: 2
Reputation: 37
You can try using Object.values(objectName)
to convert your object to array.
Upvotes: -1