type CountElementNumberToObject<T extends any[], U extends Record<PropertyKey, any[]> = {}> = T extends [infer First, ...infer Rest]
? [First] extends [never]
? CountElementNumberToObject<Rest, U>
: First extends any[]
? CountElementNumberToObject<[...First, ...Rest], U>
: CountElementNumberToObject<Rest, {
[P in keyof U | First & PropertyKey]: P extends keyof U ? P extends First ? [...U[P], any] : U[P] : [any]
}>
: {
[P in keyof U]: U[P]['length']
}
Solution by 2083335157 #34944
// 你的答案
type CountElementToObjectArr<T, Res extends Record<PropertyKey, any[]> = {}> = T extends [infer A, ...infer R] ?
[A] extends [never] ? CountElementToObjectArr<R, Res> :
A extends any[] ? CountElementToObjectArr<[...A, ...R], Res> :
A extends PropertyKey ?
CountElementToObjectArr<R, {
[P in A]: Res[P] extends any[] ? [...Res[P], never] : [never]
} & {
[P in keyof Res as P extends A ? never : P]: Res[P]
}> : Res
: Res
type CountElementNumberToObject<T> = CountElementToObjectArr<T> extends infer A ?
{
[P in keyof A]: A[P] extends any[] ? A[P]['length'] : never
}
: never
Solution by heyuelan #34728
type CountElementNumberToObject<T, Result extends {[key:keyof any]: any[]} = {}> =
T extends [infer F, ...infer R] ?
F extends any[] ? CountElementNumberToObject<[...F, ...R], Result> :
F extends keyof Result ? CountElementNumberToObject<R, {
[K in keyof Result]: F extends K ? [...Result[K], unknown]: Result[K]
}>: CountElementNumberToObject<R, {
[K in (keyof Result | F&PropertyKey)]: K extends keyof Result ? Result[K]: [unknown]
}>
:{
[K in keyof Result]: Result[K]["length"]
}
思路: 类型计算中很难做1+1=2,通常是通过数据长度来做加法,那么这里计算中途,就用unkown[]的长度来表示被计数的值的出现次数
Solution by ndfhsledk #34520
type CountElementNumberToObject<T extends any[], U extends Record<any, any[]> = {}> = T extends [infer F, ...infer R]
? [F] extends [never]
? CountElementNumberToObject<R, U>
: F extends any[]
? CountElementNumberToObject<[...F, ...R], U>
: CountElementNumberToObject<R, {
[K in (F & PropertyKey) | keyof U]: F extends keyof U
? K extends F
? [...U[K], any]
: U[K]
: [any]
}>
: { [K in keyof U]: U[K]['length'] }
Solution by MAXLZ1 #34312
type Flat<T extends any[]> = T extends [infer R, ...infer rest] ? R extends any[] ? [...Flat<R>, ...Flat<rest>] : [R, ...Flat<rest>] : T
type Count<T extends any[], V, U extends any[] = []> = T extends [infer R, ...infer rest] ? R extends V ? Count<rest, V, [...U, V]> : Count<rest, V, U> : U['length']
type CountElementNumberToObject<T extends any[], U extends any[] = Flat<T>> = {
[K in U[number]]: Count<U, K>
}
Solution by ouzexi #34118
// 你的答案
type Put<T extends Record<PropertyKey, any[]>, K extends PropertyKey> = {
[P in keyof T as P extends K ? never : P]: T[P]
} & {
[P in K]: T[P] extends any[] ? [...T[P], null] : [null]
}
type CountElementNumberToObject<T extends any[], Res extends Record<PropertyKey, any[]> = {}> =
T extends [infer A, ...infer R] ?
[A] extends [never] ? CountElementNumberToObject<R, Res> :
A extends any[] ? CountElementNumberToObject<[...A, ...R], Res> :
A extends PropertyKey ? CountElementNumberToObject<R, Put<Res, A>> : CountElementNumberToObject<R, Res>
: {
[P in keyof Res]: Res[P]['length']
}
Solution by heyuelan #33869
type Flatten<T extends any[]> = T extends [infer First, ...infer Rest]
? First extends any[]
? [...Flatten<First>, ...Flatten<Rest>]
: [First, ...Flatten<Rest>]
: [];
type Help<
T extends any[],
Obj extends { [k: PropertyKey]: any[] } = { [P in T[number]]: [] }
> = T extends [
infer First extends PropertyKey,
...infer Rest extends PropertyKey[]
]
? Help<
Rest,
{
[K in keyof Obj]: K extends First ? [...Obj[K], 1] : Obj[K];
}
>
: Obj;
type CountElementNumberToObject<Arr extends any[]> = {
[K in keyof Help<Flatten<Arr>>]: Help<Flatten<Arr>>[K]["length"];
};
Solution by sunupupup #33448
type Flatten<T extends any[]> = T extends [infer F, ...infer R]
? F extends any[]
? [...Flatten<F>, ...Flatten<R>]
: [F, ...Flatten<R>]
: []
type Count<T extends any[], X> = T extends [infer F, ...infer R]
? F extends X
? [F, ...Count<R, X>]
: [...Count<R, X>]
: []
type Mapped<T extends any[]> = {
[key in T[number]] : Count<T, key>['length']
}
type CountElementNumberToObject<T extends any[]> = Mapped<Flatten<T>>
Solution by rimo030 #32738
type Flatten<T extends {}> = {
[P in keyof T]: T[P];
};
type ExtendObjectWithNewKey<T extends {}, Key extends unknown> = Flatten<
T & {
// Sets the default value of new key to be 1
[P in (number | string) & Key]: [1]['length']
}
>;
type IncrementTheCountOfExistingKey<T extends {}, Key extends unknown> = {
// For the existing key we increment the count
[P in keyof T]: P extends Key ? [T[P], 1]['length'] : T[P]
};
type CountElementNumberToObject<
T extends unknown[] = [],
Acc extends {} = {},
> = T extends [infer F, ...infer R]
? F extends unknown[]
? CountElementNumberToObject<F, IncrementTheCountOfExistingKey<Acc, F>>
: F extends keyof Acc
? // We update its freq
CountElementNumberToObject<R, IncrementTheCountOfExistingKey<Acc, F>>
: // We add F with freq = 1
CountElementNumberToObject<R, ExtendObjectWithNewKey<Acc, F>>
: Acc;
Solution by keyurparalkar #32685
type CountElementNumberToObject<
T extends any[],
U extends Record<any, any[]> = {}
> = T extends [never]
? {}
: T extends [infer F, ...infer R]
? F extends any[]
? CountElementNumberToObject<[...F, ...R], U>
: CountElementNumberToObject<
R,
{
[K in keyof U | (F & PropertyKey)]: K extends keyof U
? K extends F
? [...U[K], any]
: U[K]
: [any];
}
>
: { [K in keyof U]: U[K]["length"] };
Solution by vangie #32203
/* Reult */
type CountElementNumberToObject<T extends unknown[]> = ArrayValueToNumberValue<
CountElement<
FlatArray<T>
>
>
/********** Helpers **********/
type FlatArray<T extends unknown[], R extends unknown[] = []> =
T extends [infer A, ...infer Rest]
? [A] extends [never]
? FlatArray<Rest, R>
: A extends unknown[]
? FlatArray<[...A, ...Rest], R>
: FlatArray<Rest, [...R, A]>
: R
type CountElement<
T extends unknown[],
Obj extends Record<string | number, number[]> = {},
> =
T extends [infer A extends string | number, ...infer Rest]
? CountElement<Rest, Omit<Obj, A> & {
[Key in A]: AddOne<Obj[A]>
}>
: Obj
type AddOne<T> = T extends number[] ? [...T, 0] : [0]
type ArrayValueToNumberValue<T extends Record<string | number, number[]>> = {
[Key in keyof T]: T[Key]['length']
}
Solution by drylint #32045
type CountElementNumberToObject<T extends unknown[]> = CENTOInternal<FlattenWithoutNever<T>>;
type FlattenWithoutNever<T extends unknown[]> =
T extends [infer Head, ...infer Tail]
? [Head] extends [never]
? [...FlattenWithoutNever<Tail>]
: Head extends unknown[]
? [...FlattenWithoutNever<Head>, ...FlattenWithoutNever<Tail>]
: [Head, ...FlattenWithoutNever<Tail>]
: []
;
type CENTOInternal<T extends unknown[], Acc extends Record<PropertyKey, any> = {}> =
T extends [infer Head extends PropertyKey, ...infer Tail]
? Acc[Head] extends number
? CENTOInternal<Tail, PlusOne<Acc, Head>>
: CENTOInternal<Tail, AddProperty<Acc, Head>>
: Acc
;
type PlusOne<T, Property> = {
[P in keyof T]: P extends Property ? PlusOneInternal<T[P]> : T[P];
}
type PlusOneInternal<T, Acc extends 1[] = []> =
T extends Acc["length"]
? [...Acc, 1]["length"]
: PlusOneInternal<T, [...Acc, 1]>
;
type AddProperty<L, R extends PropertyKey> = {
[P in keyof L | R]:
P extends keyof L
? L[P]
: 1;
}
Solution by sdrjs #31876
// 你的答案
type MyRqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
type ExpandArray<T extends any[] | string | number> =
T extends [infer S, ...infer O] ?
S extends any[] ? [...ExpandArray<S>, ...ExpandArray<O>] : [S, ...ExpandArray<O>]
: [];
type ItemInArrayCount<A extends any[], I, C extends any[] = []> = A extends [infer S, ...infer O] ? (MyRqual<I, S> extends true ? ItemInArrayCount<O, I, [1, ...C]> : ItemInArrayCount<O, I, [...C]> ) : C['length'];
type CountElementNumberToObject<T extends any[], U extends any[] = ExpandArray<T>> = {
[P in U[number]]: ItemInArrayCount<U, P>;
}
Solution by tarotlwei #31747
type Flatten<T,R extends any[] = []> =
T extends [infer F,...infer L]?
[F] extends [never]?
Flatten<L,R>:
F extends any[]?
Flatten<L,[...R,...Flatten<F>] >
:Flatten<L,[...R,F]>
:R
type Count<
T,
R extends Record<string | number,any[]> = {}
> =
T extends [infer F extends string | number,...infer L]?
F extends keyof R?
Count<L, Omit<R,F>& Record<F,[...R[F],0] > >
: Count<L, R & Record<F,[0]>>
:{
[K in keyof R]:R[K]['length']
}
type CountElementNumberToObject<
T
> =
Count<Flatten<T>>
Solution by MyeonghoonNam #31324
type Flatten<T,R extends any[] = []> =
T extends [infer F,...infer L]?
[F] extends [never]?
Flatten<L,R>:
F extends any[]?
Flatten<L,[...R,...Flatten<F>] >
:Flatten<L,[...R,F]>
:R
type Count<
T,
R extends Record<string | number,any[]> = {}
> =
T extends [infer F extends string | number,...infer L]?
F extends keyof R?
Count<L, Omit<R,F>& Record<F,[...R[F],0] > >
: Count<L, R & Record<F,[0]>>
:{
[K in keyof R]:R[K]['length']
}
Solution by gearonixx #31166
type Flatten<T, R extends any[] = []> = T extends [infer F, ...infer L]
? [F] extends [never]
? Flatten<L, R>
: F extends any[]
? Flatten<L, [...R, ...Flatten<F>]>
: Flatten<L, [...R, F]>
: R;
type CountElementNumberToObject<
T extends unknown[],
U extends any[] = Flatten<T>,
R extends Record<any, unknown[]> = { [K in U[number]]: [] },
> = U extends [infer F, ...infer Rest]
? CountElementNumberToObject<T, Rest, { [K in keyof R]: K extends F ? [...R[K], unknown] : R[K] }>
: {
[K in keyof R]: R[K]['length'];
};
Solution by leejaehyup #30866
type Flat<T> = T extends [infer A, ...infer B] ? A extends any[] ? [...Flat<A>, ...Flat<B>] : [A, ...Flat<B>] : T
type Count<T, O, U extends any[] = []> = T extends [infer A, ...infer B] ? A extends O ? Count<B, O, [...U, O]> : Count<B, O, [...U]> : U['length']
type CountElementNumberToObject<T extends any[], U extends any[] = Flat<T>> = {
[K in U[number]] : Count<U, K>
}
Solution by dreamluo-plus #30686
// your answers
type CountElementNumberToObject<T extends any[], U extends {any?:any[]} ={}> =
T extends [infer F, ...infer R]?
[F] extends [never]? CountElementNumberToObject<R, U>:
F extends any[]? CountElementNumberToObject<F, U>:
F extends keyof U?
CountElementNumberToObject<R, {[K in keyof U]: U[K] extends any[]? K extends F? [...U[K], 1]: U[K]:never}>
: CountElementNumberToObject<R, {[K in keyof U | (F extends PropertyKey? F: never)]: K extends keyof U? U[K]: [1]}>
: {
[K in keyof U]: U[K] extends any[]? U[K]['length']: never
}
Solution by yangyyou #30486
type Merge<A extends Record<keyof any, any[]>, B extends Record<keyof any, any[]>> = {
[K in keyof A | keyof B]:
K extends keyof A
? K extends keyof B
? [...A[K], ...B[K]]
: A[K]
: B[K]
}
type CountElement<T, M extends Record<keyof any, unknown[]> = {}> = T extends [infer F, ...infer Rest]
? [F] extends [never]
? CountElement<Rest, M>
: F extends any[]
? CountElement<Rest, CountElement<F> extends Record<keyof any, any[]> ? Merge<M, CountElement<F>> : M>
: CountElement<Rest, Merge<M, { [K in F & keyof any]: [unknown] }>>
: M
type Count<T extends Record<keyof any, any[]>> = {
[K in keyof T]: T[K]['length']
}
type CountElementNumberToObject<T> = Count<CountElement<T>>
Solution by XkSuperCool #30347
// 你的答案
type CountElementNumberToObject<T extends any[], U extends { any?: any[] } = {}> =
T extends [infer F, ...infer R] ?
[F] extends [never] ? CountElementNumberToObject<R, U> :
F extends any[] ?
CountElementNumberToObject<F, U> :
CountElementNumberToObject<R,
{
[P in keyof U | (F extends PropertyKey ? F : never)]: P extends keyof U ? P extends F ? U[P] extends any[] ? [...U[P], ''] : U[P] : U[P] : ['']
}>
: {
[P in keyof U]: U[P] extends any[] ? U[P]['length'] : never
}
Solution by YE840926098 #30140
type PlusOne<
N extends number,
Acc extends number[] = []
> = Acc["length"] extends N ? [...Acc, 0]["length"] : PlusOne<N, [...Acc, 0]>;
type CountElementNumberToObject<
T extends any[],
R extends { [key: number]: number } = {}
> = T extends [never]
? R
: T extends [infer First, ...infer Rest]
? First extends any[]
? CountElementNumberToObject<[...First, ...Rest], R>
: CountElementNumberToObject<
Rest,
{
[Key in keyof R | First]: Key extends keyof R
? Key extends First
? PlusOne<R[Key]>
: R[Key]
: 1;
}
>
: R;
Solution by idebbarh #29959
/**转化为
* {
* 1: [1, 1]
* 2: [1, 1]
* 3: [1, 1]
* 4: [1]
* 5: [1]
* }
*/
type CountElementNumberCounter<T extends any[], _Counter extends { [x: PropertyKey]: 1[] } = {}> =
T extends [infer F extends PropertyKey | any[], ...infer R] ?
(
CountElementNumberCounter<R, F extends any[] ?
CountElementNumberCounter<F, _Counter> :
F extends PropertyKey ?
{ [P in keyof _Counter | F]: P extends keyof _Counter ? F extends P ? [..._Counter[P], 1] : _Counter[P] : [1] }/*pop*/ : never>
) : _Counter/*return*/;
type CountElementNumberToObject<T extends any[], U extends { [x: PropertyKey]: 1[] } = CountElementNumberCounter<T>> = [U] extends [never] ? {} : { [P in keyof U]: U[P][`length`] };
Solution by E-uler #29009
type Flat<T extends unknown[]> = T extends [infer Item, ...infer Rest]
? [Item] extends [never]
? Flat<Rest>
: Item extends unknown[]
? [...Flat<Item>, ...Flat<Rest>]
: [Item, ...Flat<Rest>]
: [];
type CountElementNumberToObject<
T extends unknown[],
F extends unknown[] = Flat<T>,
Res extends Record<keyof any, readonly unknown[]> = {}
> = F extends [infer Item, ...infer Rest]
? Item extends keyof any
? CountElementNumberToObject<
T,
Rest,
Omit<Res, Item> & {
[K in Item]: K extends keyof Res ? [...Res[K], unknown] : [unknown];
}
>
: CountElementNumberToObject<T, Rest, Res>
: { [K in keyof Res]: Res[K]["length"] };
Solution by DoubleWoodLin #28860
type Value = number | string | never;
type Item = Value | Item[];
type GetMap<
V extends Value,
Map extends Record<Value, 0[]> = {}
> = V extends keyof Map
? Omit<Map, V> & Record<V, [...Map[V], 0]>
: Map & Record<V, [0]>;
type Count<T extends Item[], Map extends Record<Value, 0[]> = {}> = T extends [
infer F,
...infer R extends Item[]
]
? [F] extends [never]
? Map
: F extends Item[]
? Count<[...F, ...R], Map>
: F extends Value
? Count<R, GetMap<F, Map>>
: Map
: Map;
type CountMap<T extends Record<Value, 0[]>> = {
[K in keyof T]: T[K]["length"];
};
type CountElementNumberToObject<T extends Item[]> = CountMap<Count<T>>;
Solution by frontlich #28802
type DigsNext = { '0': '1', '1': '2', '2': '3', '3': '4', '4': '5', '5': '6', '6': '7', '7': '8', '8': '9' }
type AddOne<A extends number | string> = `${ A }` extends `${ infer AH }${ infer AT }`
? AH extends '9'
? `0${ AddOne<AT> }`
: `${ DigsNext[AH & keyof DigsNext] }${ AT }`
: '1'
type ToNumber<T> = T extends string | number
? `${ T }` extends `${ infer I extends number }` ? I : never
: never
type ToArrayNumber<T, _R extends unknown[] = []> = T extends [ infer I, ...infer Rest ]
? [I] extends [number | string]
? `${ I }` extends `${ infer NI extends number }`
? ToArrayNumber<Rest, [ ..._R, NI ]>
: never
: ToArrayNumber<Rest, [ ..._R, I]>
: _R
type CountElementNumberToObject<
T extends unknown[],
_R extends Record<number, number> = {},
> = ToArrayNumber<T> extends [ infer I, ...infer Rest ]
? [I] extends [number]
? CountElementNumberToObject<Rest, Omit<_R, I> & Record<I, ToNumber<AddOne<_R[I]>>>>
: I extends unknown[]
? CountElementNumberToObject<[ ...I, ...Rest], _R>
: {}
: { [K in keyof _R]: _R[K] }
Solution by lvjiaxuan #28470
type Item = PropertyKey | Item[];
type CountOccurrences<
Items extends unknown[],
OccurrencesByKey extends Record<PropertyKey, 0[]> = {}
> = Items extends [infer Head, ...infer Tail extends Item[]]
? CountOccurrences<
Tail,
[Head] extends [never]
? OccurrencesByKey
: Head extends PropertyKey
? {
[Key in keyof OccurrencesByKey | Head]: Key extends Head
? Key extends keyof OccurrencesByKey
? [...OccurrencesByKey[Key], 0]
: [0]
: OccurrencesByKey[Key];
}
: Head extends Item[]
? CountOccurrences<Head, OccurrencesByKey>
: never
>
: OccurrencesByKey;
type CountElementNumberToObject<ItemArray extends Item[]> =
CountOccurrences<ItemArray> extends infer OccurrencesByKey extends Record<
PropertyKey,
0[]
>
? { [Key in keyof OccurrencesByKey]: OccurrencesByKey[Key]["length"] }
: never;
Solution by yevhenpavliuk #28421
type Flatten<T,R extends any[] = []> =
T extends [infer F,...infer L]?
[F] extends [never]?
Flatten<L,R>:
F extends any[]?
Flatten<L,[...R,...Flatten<F>] >
:Flatten<L,[...R,F]>
:R
type Count<
T,
R extends Record<string | number,any[]> = {}
> =
T extends [infer F extends string | number,...infer L]?
F extends keyof R?
Count<L, Omit<R,F>& Record<F,[...R[F],0] > >
: Count<L, R & Record<F,[0]>>
:{
[K in keyof R]:R[K]['length']
}
type CountElementNumberToObject<
T
> =
Count<Flatten<T>>
Solution by jiangshanmeta #28355
type Flatten<T extends unknown[]> = T extends [infer F, ...infer R]
? F extends unknown[]
? [...Flatten<F>, ...Flatten<R>]
: [F, ...Flatten<R>]
: []
// Get an initial object containing all the keys
type Map<T extends unknown[]> = {
[K in T[number] as K extends string | number ? K : never]: []
}
// Core logic to iterate the tuple and recursively increment the mapped tuple assoicated with a specific key
type GetTupledObject<T extends unknown[], Dump extends Record<string | number, unknown[]> = Map<Flatten<T>>> =
T extends [infer F, ...infer R]
? F extends unknown[]
? GetTupledObject<F, Dump>
: F extends string | number
? GetTupledObject<R, {
[P in keyof Dump]: P extends F
? [...Dump[P], unknown]
: Dump[P]
}>
: {}
: Dump
// Special case handling
// and count by each tuple's length
type CountElementNumberToObject<T extends unknown[]> =
GetTupledObject<T> extends infer G
? [G] extends [never]
? {}
: {
[P in keyof G]: G[P] extends unknown[] ? G[P]['length'] : never
}
: never
Solution by jazelly #28320