Пытаюсь разобраться с дженериками и задаюсь вопросом, правильно ли я применяю их здесь.
Рассмотрим следующее:
interface NameValuePair {
name: string;
value: string;
}
function flatten(data: NameValuePair[]) {
return data.reduce((obj, pair: NameValuePair) => {
obj[pair.name] = pair.value;
return obj;
}, {});
}
const formData: NameValuePair[] = [
{ name: "firstName", value: "John" },
{ name: "lastName", value: "Doe" }
];
let flattened = flatten(formData);
// { firstName: "John", lastName: "Doe" }
Всякий раз, когда вызывается функция, я бы хотел, чтобы Typescript принудительно использовал настраиваемый интерфейс, описывающий окончательную структуру данных. Например, используя formData
сверху, возможный интерфейс может выглядеть так:
interface ProfileForm {
firstName: string;
lastName: string;
}
Ниже приведена моя попытка использовать дженерики:
function flatten<T>(formData: NameValuePair[]): T {
return <T>formData.reduce((obj: T, pair: NameValuePair) => {
obj[pair.name] = pair.value;
return obj;
}, {});
}
let flattened = flatten<ProfileForm>(formData);
let firstName = flattened.firstName;
let age = flattened.age; // typescript error
Он работает, как и ожидалось, но при тестировании он дает те же результаты, что и:
function flatten(formData: NameValuePair[]) {
return formData.reduce((obj, pair: NameValuePair) => {
obj[pair.name] = pair.value;
return obj;
}, {});
}
let flattened = <ProfileForm>flatten(formData);
let firstName = flattened.firstName;
let age = flattened.age; // typescript error
В данном конкретном случае дают ли дженерики какую-либо пользу?