I see the value of Partial
, Required
, Pick
and Omit
, but implementing each of these as custom special forms in the type system doesn’t strike me as the best approach.
In TypeScript, these are not special-cased operators. Rather, they are built on a small number of more general type operators that allow other useful transforms (Readonly
, Record
, Exclude
, Extract
, etc.) to be built. These operators give TypeScript a “super power” that Python’s type system currently lacks.
For context, here are the definitions for Partial
, Required
, Pick
, and Omit
in TypeScript:
// Make all properties in T optional
type Partial<T> = {
[P in keyof T]?: T[P];
};
// Make all properties in T required
type Required<T> = {
[P in keyof T]-?: T[P];
// From T, pick a set of properties whose keys are in the union K
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
// Construct a type with the properties of T except for those in type K.
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Before converging on a concrete proposal for how to implement these in the Python type system, I encourage you to consider more generalized solution like the one found in TypeScript. I started to explore this idea here but didn’t fully flesh it out.
We may decide in the end that hard-coding the behavior of a handful of these transforms is the only viable solution, but that feels to me like a missed opportunity.