Указание на конкретный тип в объекте, typescript
есть следующая функция - трансформер, написанная на Typescript. Во входном объекте я указываю объект - словарь, ru, en, ключи могут быть как просто строки, так и функции которые возвращают строки. В выходном объекте, хочу чтобы typescript указывал на тип конкретного поля, тайпскрипт указывает на все типы:
код:
const dictionary = {
ru: {
plainText: 'Простой текст',
textFunction: (temp: number) => `Добавить +${temp}`
},
en: {
plainText: 'Plain text',
textFunction: (temp: number) => `Add +${temp}`
}
}
const transformObject = <Obj extends Object = any, K extends keyof Obj = any>(
obj: Obj,
) => {
return (Object.keys(obj) as K[]).reduce((acc, translationKey) => {
const translationObject = obj[translationKey];
const translates = (
Object.keys(translationObject) as Array<keyof Obj[K]>
).reduce((acc, langKey) => {
return {
...acc,
[langKey]: {
[translationKey]: translationObject[langKey],
},
};
}, {});
return merge(acc, translates);
}, {}) as {
[Langs in keyof Obj[K]]: {
[T in keyof Obj]: Obj[K][keyof Obj[K]];
};
};
};
const locales = transformObject(dictionary);
на выходе получаем следующую структуру:
/**
* {
* ru: {
* plainText: string | (temp: number) => string;
* textFunction: string | (temp: number) => string;
* }
* en: {
* plainText: string | (temp: number) => string;
* textFunction: string | (temp: number) => string;
* }
* }
*
*/
Хотелось бы получить это:
/*
* {
* ru: {
* plainText: string;
* textFunction: (temp: number) => string;
* }
* en: {
* plainText: string
* textFunction: (temp: number) => string
* }
* }
*
*/
Ответы (1 шт):
Автор решения: nörbörnën
→ Ссылка
type TTransformDictionary<T extends object> = {
[K2 in keyof T[keyof T]]: { [K1 in keyof T]: T[K1][K2] }
};
const dictionary = {
ru: {
plainText: 'Простой текст',
textFunction: (temp: number) => `Добавить +${temp}`
},
en: {
plainText: 'Plain text',
textFunction: (temp: number) => `Add +${temp}`
}
};
const transformObject = <T extends object>(obj: T): TTransformDictionary<T> => {
// your code here
return null as unknown as TTransformDictionary<T>;
};
const locales = transformObject(dictionary);
Результат:
const locales: {
plainText: {
ru: string;
en: string;
};
textFunction: {
ru: (temp: number) => string;
en: (temp: number) => string;
};
}
Eсли вашу задачу (как я её понял) писать на настоящем typescript то код должен был бы быть таким. Обратите внимание на типизацию, сама транформация данных не так уж важна.