I have array. I want to create an object with properties of the array with specific type for each of them.
export interface SomeNumbers {
name: string;
value: number;
}
const arr = ['first', 'second', 'third'];
const objectOfValues = {}; // HOW TO SET A TYPE HERE?
arr.forEach((val, index) => {
objectOfValues[val]= {
name: val,
value: index
};
});
CodePudding user response:
I think you are trying to do something like this:
export interface SomeNumbers {
name: string;
value: number;
}
const arr = ['first', 'second', 'third'];
const objectOfValues: { [key: string]: SomeNumbers } = {};
arr.forEach((val, index) => {
objectOfValues[val] = {
name: val,
value: index
};
});
CodePudding user response:
You can use reducer pattern for both type and runtime scopes.
export interface SomeNumbers<N, V> {
name: N;
value: V;
}
type Reducer<
Tuple extends Array<any>,
Acc extends Record<string, any> = {},
Index extends number[] = []
> =
Tuple extends []
? Acc
: (Tuple extends [infer Head, ...infer Tail]
? (Head extends PropertyKey
? Reducer<
Tail,
Acc & Record<Head, SomeNumbers<Head, Index['length']>>,
[...Index, 1]
>
: never)
: never)
const builder = <Tuple extends string[]>(tuple: [...Tuple]) =>
tuple.reduce((acc, elem, index) => ({
...acc,
[elem]: {
name: elem,
value: index
}
}), {} as Reducer<Tuple>)
const result = builder(['first', 'second', 'third'])
// {
// name: "first";
// value: 0;
// }
result.first
Reducer
type does exactly the same job as builder
function. Except Reducer
iterates recursively through the tuple.
Reducer
- iterates recursively through the Tuple
and intersects Acc
with SomeNumbers<N,V>
. Index
- is extra tuple for indexing. Every time I increasing Index
tuple for 1 element. It just coresponds to the index of iterated element
You can find more examples in my blog