You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OptionalPropNames<T>: unexpected result in conditional type #21989
// Type-level filters to extract just the required or optional properties of a type// Defns from https://github.com/Microsoft/TypeScript/pull/21919#issuecomment-365491689typeOptionalPropNames<T>={[PinkeyofT]: undefinedextendsT[P] ? P : never}[keyofT];typeRequiredPropNames<T>={[PinkeyofT]: undefinedextendsT[P] ? never : P}[keyofT];typeOptionalProps<T>={[PinOptionalPropNames<T>]: T[P]};typeRequiredProps<T>={[PinRequiredPropNames<T>]: T[P]};// Let's extract just the optional property names in a typetypePropNames=OptionalPropNames<{req: string,opt?: number}>;// Names = "opt" | undefined
Expected behavior: PropNames = "opt"
Actual behavior: PropNames = "opt" | undefined. How did that undefined get in there?
Related Issues:
Noticed this while writing up #21988, but wasn't sure if the cause was related or not.
The RequiredProps and OptionalProps definitions come from #21919 (comment)
I worked it out. This is a result of the way mapped types carry over modifiers (readonly, ?) from the source type to the mapped type. This can be addressed using the new -? syntax added in #21919:
typeOptionalPropNames<T>={[PinkeyofT]-?: undefinedextendsT[P] ? P : never}[keyofT];// ^^ new syntax to remove optional modifierstypePropNames=OptionalPropNames<{req: string,opt?: number}>;// PropNames = "opt" ✓✓
Activity
yortus commentedon Feb 20, 2018
I worked it out. This is a result of the way mapped types carry over modifiers (
readonly,?) from the source type to the mapped type. This can be addressed using the new-?syntax added in #21919: