Microsoft/TypeScript

Combination of intersection type, mapped type and generic type seem to break type checks for nested properties

Open

#49,638 opened on Jun 22, 2022

View on GitHub
 (3 comments) (2 reactions) (0 assignees)TypeScript (6,726 forks)batch import
BugDomain: Mapped TypesHelp Wanted

Repository metrics

Stars
 (48,455 stars)
PR merge metrics
 (Avg merge 6d 17h) (9 merged PRs in 30d)

Description

Bug Report

🔎 Search Terms

mapped types, generic bound, nested objects

🕗 Version & Regression Information

We've detected this on 4.7.4. Checking previous versions on playgrounds, last one where it worked correctly is 3.5.1. It is also reproducible on current nightly build.

  • This changed between versions 3.5.1 and 3.6.3

⏯ Playground Link

Playground link with relevant code

💻 Code

type BaseType = {
  select?: { id?: boolean} ,

  where: {},
}

type FullType = BaseType & {
  anything?: boolean
}

type MappedType<T> = {
  [key in keyof T]:  T[key]
}

declare function genericFunction<T extends FullType>(args: MappedType<T>): void

genericFunction({
  where: {},
  select: {
    id: true,
    // this should not pass
    shouldErrorHere: 'lalalala'
  }
})

🙁 Actual behavior

The code passes typechecks

🙂 Expected behavior

shouldErrorHere property should not be allowed in that position, since it's not defined on typeof BaseType['select']. Doing any of the following causes expected error to appear:

  1. Removing intersection type and making FullType a plain alias for BaseType
  2. Making where property optional in BaseType definition
  3. Removing anything property from FullType
  4. Adding any non-optional property to the intersection
  5. Omitting where property in genericFunction call
  6. Passing incorrect anything value during the call
  7. Changing FullType to interface FullType extends BaseType

Contributor guide