TypeScript Version: 2.8.0-dev.20180216
Code
// Type-level filters to extract just the required or optional properties of a type// Defns from https://github.com/Microsoft/TypeScript/pull/21919#issuecomment-365491689typeRequiredPropNames<T>={[PinkeyofT]: undefinedextendsT[P] ? never : P}[keyofT];typeOptionalPropNames<T>={[PinkeyofT]: undefinedextendsT[P] ? P : never}[keyofT];typeRequiredProps<T>={[PinRequiredPropNames<T>]: T[P]};typeOptionalProps<T>={[PinOptionalPropNames<T>]: T[P]};// Some object types with different numbers of propstypeP2={a: string,b: number};// Two propstypeP1={a: string};// One proptypeP0={};// No props// Let's extract only the required properties of P0, P1, and P2typeP2Names=RequiredPropNames<P2>;// P2Names = "a" | "b" ✓😊typeP1Names=RequiredPropNames<P1>;// P1Names = "a" ✓😊typeP0Names=RequiredPropNames<P0>;// P0Names = any ?😕typeP2Props=RequiredProps<P2>;// P2Props = { a: string; b: number; } ✓😊typeP1Props=RequiredProps<P1>;// P1Props = { a: string; } ✓😊typeP0Props=RequiredProps<P0>;// P0Props = { [x: string]: any } ?😕Expected behavior:
P0Names = never and P0Props = {}
Actual behavior:
P0Names = any and P0Props = {[x: string]: any}
Notes:
Anders Hejlsberg (@ahejlsberg) helpfully came up with the RequiredProps and OptionalProps definitions above from a question I asked in #21919. They work great except when T = {}
Not 100% sure if this is a bug or not, but it's definitely counterintuitive. RequiredProps works for any object type except the empty one, when a string indexer suddenly appears. It certainly breaks the semantic expectations of RequiredProps.
Workaround:
The following version of RequiredPropNames achieves the expected behaviour by singling out the {} case:
typeRequiredPropNames<T>=keyofTextendsnever
? never
: {[PinkeyofT]: undefinedextendsT[P] ? never : P}[keyofT];
TypeScript Version: 2.8.0-dev.20180216
Code
Expected behavior:
P0Names = neverandP0Props = {}Actual behavior:
P0Names = anyandP0Props = {[x: string]: any}Notes:
Anders Hejlsberg (@ahejlsberg) helpfully came up with the
RequiredPropsandOptionalPropsdefinitions above from a question I asked in #21919. They work great except whenT = {}Not 100% sure if this is a bug or not, but it's definitely counterintuitive.
RequiredPropsworks for any object type except the empty one, when a string indexer suddenly appears. It certainly breaks the semantic expectations ofRequiredProps.Workaround:
The following version of
RequiredPropNamesachieves the expected behaviour by singling out the{}case: