Home > Net >  'T[string]' is not assignable to type 'Record<string, any>'
'T[string]' is not assignable to type 'Record<string, any>'

Time:01-24

Starting typescript 4.7.4, the PrefixedRecord in my Flatten type is now broken and can't be indexed by the keys provided.

Can someone suggest a quick workaround or another way to fix this?

Appreciate the help !

export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
declare type StringKeysOf<T> = Extract<keyof T, string>;
declare type PrefixedRecord<Prefix extends string, Obj extends Record<string, any>> = {
    [Key in StringKeysOf<Obj> as `${Prefix}.${Key}`]: Obj[Key];
};
declare type NonObjectKeysOf<T> = {
    [K in keyof T]: T[K] extends Array<any> ? K : T[K] extends object ? never : K;
}[keyof T];
declare type ObjectKeysOf<Obj> = Exclude<keyof Obj, NonObjectKeysOf<Obj>>;
export declare type Flatten<T, K extends StringKeysOf<T> = StringKeysOf<T>> = UnionToIntersection<K extends ObjectKeysOf<T> ? PrefixedRecord<K, T[K]> : {
    [k in K]: T[K];
}>;

enter image description here

Playground Link

CodePudding user response:

You can check if T[K] extends Record<string, any> so it will be happy to be used in PrefixedRecord.

export declare type Flatten<T, K extends StringKeysOf<T> = StringKeysOf<T>> = UnionToIntersection<K extends ObjectKeysOf<T> ? T[K] extends Record<string, any> ? PrefixedRecord<K, T[K]> : never : {
    [k in K]: T[K];
}>;

Playground

I'm sure there's a way to re-write the whole thing to make it more elegant, but this should work fine.

  • Related