Background: (can be skipped)
I was fiddling around to make some update(person: Person) statement more usable by allowing a subset of properties it should update. I was thinking there are 2 options:
- The id is passed explicitly to the update method as the first argument, and then
Partial<Person>orOmit<Person, 'id'>as the 2nd argument. - Or, the update method's signature remains as is, with only 1 input arg, and enforces that the
idproperty is in the object provided.
So Omit seems like a good candidate to me, but the keys to omit can be of any string value.
Question:
Why does TypeScript not enforce the value of the keys provided to Omit ? Is there any good use not to which I am overseeing?
See the following code
export interface Person {
id: string;
age: number;
name: string;
}
type UpdatePerson = Omit<Person, 'whatEver'>; // Why does 'whatEver' not cause compile issues?
type UpdatePerson2 = Pick<Person, 'id'> & Partial<Person>; // Great, a valid key is enforced here
type UpdatePerson3 = Pick<Person, 'thisDoesNotCompile'> & Partial<Person>; // This line fails compilation as that property isn't part of the interface
For now I go with update(person: UpdatePerson) and type UpdatePerson = Pick<Person, 'id'> & Partial<Person>;. This makes all properties optional, and the id mandatory.
In short, this behavior was selected so the built-in
Omitcould be most compatible with existing DefinitelyTyped libraries. Those libraries were already split on whether Omit should be strict, and picking a looser Omit prevented those existing libraries from breaking at the expense of slightly less compiler safety and autocomplete for code yet to be written.For background: this was requested in microsoft/TypeScript#30825, with this response from DanielRosenwasser:
And these from language co-author Ryan Cavanaugh:
It is a popular request with duplicates here on SO and on GitHub, and corresponding concise strict equivalents are easy to write/derive and also available in other libraries like
type-zoo.