1

On a scenario to have a pointfree omit i can do this:

type PlainObject<T> = {[key: string]: T}

const omit = <K extends string>(
  name: K
) => <T, U extends PlainObject<T> & {
  [P in K]: T
}>(
  x: U,
): Partial<U> => {
  throw new Error ('Yet to implement !')
}

Is they're a way to use K as an array of string instead of a string? Something along the line of this:

const omit = <K extends string[]>(
  ...names: K
) => <T, U extends PlainObject<T> & {
  [P in K]: T // Type 'K' is not assignable to type 'string | number | symbol'
}>(
  x: U,
): Partial<U> => {
  throw new Error ('Yet to implement !')
}

The goal is to be able to have the compiler complains if a user enters a wrong object according to the key passes: omit ('a', 'b') ({b: 3, c: 4}) // => expect error

Thanks in advance
Seb

4
  • 1
    If K is an array of strings, then you want to map over K[number], not K. So {[P in K[number]]: T} should work for you, I guess. It's hard to be 100% sure because the code doesn't seem to be a minimal reproducible example (what is PlainObject<T>? why is there a T and a U in the returned function, when T will almost certainly not be inferred as anything but {}? what is the intended return type of the returned function?) Commented Dec 19, 2018 at 1:35
  • Sorry for that - forgot to put it, basically it's a Record<string, T>, and i'm using PlainObject to be able to extends it. T can be usefull since when an object is passed it's an object of number as values, those would be inferred without issue (I might be wrong, but based on the documentations i've red is whenever you can try to adds generics for better inference - it's not needed?) - as for U what I want is to have a PlainObject has a return object but containing some of the keys of the original object (in the implementation i put all the copied items in a Partial<U> Commented Dec 19, 2018 at 1:57
  • besides that your solution works just fine - if you can quickly post an answer so I can validates it it would be cool ;) Besides where can I find docs in this process of indexing tuple (as in K[number]) in order to better appreciates it? I see it use often on pieces of codes but still hasn't grasp it Commented Dec 19, 2018 at 1:59
  • And last but not least, instead of using Partial U is theyre a way of reconstructing precisely the object resulting from a call to omit using the key of U (which we know) for keeping only the one that aren't removed? It would be a better experience that instead of optional (and possibly missing keys) the resulting object only actual keys ^^ Commented Dec 19, 2018 at 2:02

1 Answer 1

3

Yes, it's possible:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

declare function omit<K extends string>(...properties: K[]):
  <T extends Record<K, any>>(source: T) => Omit<T, K>;

Usage:

interface Foo {
  name: string;
  age: number;
  brand: symbol;
}

declare const foo: Foo;

omit('age', 'name')(foo); // $ExpectType { brand: symbol }
omit('foo', 'bar')(foo);  // $ExpectError
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.