Интересный вопрос, но, похоже, нет однозначного ответа. Но вот одна попытка:
export function renameProperty<
T extends {},
OP extends keyof T,
NP extends string,
R = Omit<T, OP> & Record<NP, T[OP]>
>(oldProp: OP, newProp: NP, { [oldProp]: value, ...others }: T): R {
return {
[newProp]: value,
...others
} as any; // *
}
Это имеет то преимущество, что возвращает правильный тип с удаленным oldProp
и добавленным newProp
.
1008 * то есть *
const c = renameProperty("foo", "bar", { foo: 1, baz: "spam", holy: "grenade" });
console.log(c.foo, c.bar, c.baz, c.holy);
/// complains here, that 'foo' is not available in c
/// typeof c.bar === "number"
*
К сожалению, TS не может определить правильный тип из {[newProp]: value}
, а результирующий тип - { [x: string]: ... }
, поэтому, к сожалению, необходим ужасный as any
(по крайней мере, я не нашел способа его удалить - не уверен, что это ошибка или ограничение).
Omit
: Исключить свойство из типа