В настоящее время я пытаюсь написать функцию более высокого порядка without
, которая будет возвращать новый объект без ключей, переданных в возвращаемую функцию.
Я не вижу способа заставить ключ в редукторе быть keyof T
, поскольку Object.keys
возвращает string[]
, а не Array<keyof T>
, если бы это было так, я думаю, это решило бы эту проблему. Я упускаю что-то очевидное с типами здесь, которые решат эту проблему?
const without = <T>(object: T) => (...parts: Array<keyof T>) => {
return Object.keys(object).reduce((acc, key) => {
// `key` is of type `string` not `keyof T`
if (!parts.includes(key)) {
acc[key] = object[key];
}
return acc;
}, {} as Omit<T, typeof parts[number]>);
};
const obj = { a: 1, b: 2, c: 3 };
const result = without(obj)('a', 'c');
Object.keys
вернется string[]
по причинам, изложенным здесь. Вам нужно будет использовать утверждения типа, чтобы сделать эту работу.
const without = <T>(object: T) => <K extends keyof T>(...parts: Array<K>): Omit<T, K> => {
return (Object.keys(object) as Array<keyof T>).reduce((acc, key) => {
if (!parts.includes(key as any)) {
acc[key] = object[key];
}
return acc;
}, {} as T);
};
const obj = { a: 1, b: 2, c: 3 };
const result = without(obj)('a', 'c');
Помимо утверждения Array<keyof T>
я также изменил тип начального значения reduce
на T
. Это приказ о разрешении задания acc[key] = object[key]
. T[keyof T]
будет назначаться самому себе, но Omit<T, typeof parts[number]>[keyof T]
назначаться нельзя. T
, в свою очередь, будет присвоено Omit<T, typeof parts[number]>
@TitianCernicova-Dragomir, это имеет смысл, и, наконец, понимание того, почему Object.keys
возвращает string[]
, бесценно, спасибо!
Вам также нужно будет ввести общий параметр во внутреннюю функцию, иначе
typeof parts[number]
не будет работать typescriptlang.org/play?jsx=0#code/…