Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Mapped Types should distribute over union types #28339

Copy link
Copy link
@Jessidhia

Description

@Jessidhia
Issue body actions

Search Terms

Mapped Type Union

Suggestion

This might be a bug or an intentional consequence of the original design, but mapped types do not distribute over union types. The example below demonstrates what happens:

type Foo = { x: false; foo?: string }
type Bar = { x: true; foo: string }

type FooOrBar = Foo | Bar

type MappedFooOrBar = Pick<FooOrBar, keyof FooOrBar>

// the type of MappedFooOrBar will be { x: boolean; foo: string | undefined }
// note how foo is now required even with x = false
// and also how you're now allowed to set foo = undefined even with x = true

Use Cases

Higher order components that receive components whose props are union types.

This usually is not a problem but it is a problem if you are going to use Pick (or Omit) on their props. This is already a problem with react-redux's connect for example.

Examples

type Foo = { x: false; foo?: string }
type Bar = { x: true; foo: string }

type FooOrBar = Foo | Bar

// input is a union type so this should distribute
type MappedFooOrBar = Pick<FooOrBar, keyof FooOrBar>
// should be equivalent to a MappedFooOrBar that distributes over its input
type MappedFooBar = Pick<Foo, keyof FooOrBar> | Pick<Bar, keyof FooOrBar>

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
    • It probably is breaking but is a "good break" as far as I can tell.
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.