Skip to content

Combination of generic type and mapped types produce unexpected bahaviour #32807

Closed
@liaokaien

Description

@liaokaien

I've tried my best to search for related issues and read the document thoroughly but failed to find any useful information. I'm sorry if this bug turns out to be duplicate or even not a bug at all.

TypeScript Version: 3.5.2

Search Terms: conditional types, mapped types, generic

Code

type Concrete = {
  keyOne: string
  keyTwo: string
}

type ConcreteKey = keyof Concrete

type R<T, N extends keyof T> = {
  [P in keyof T]: P extends N ? true : false
};
// R implement without conditional types
type Q<T, N extends keyof T> = {
  [P in N]: true
} & {
  [P in Exclude<keyof T, N>]: false
};
// Function using a concrete type, works as expected
function fn(keys: ConcreteKey[]) {
  let temp: Partial<R<Concrete, ConcreteKey>> = {}
  keys.forEach(key => temp[key] = true)
}
// Function use generic types, report a weird error:
// Type 'true' is not assignable to type 'K extends K ? true : false'.ts(2322)
function fn2<T, K extends keyof T>(keys: K[]) {
  let temp: Partial<R<T, K>> = {}
  keys.forEach(key => temp[key] = true)
}

Expected behavior:
Any property of type R<T,K> could be assigned to true if it extends type K; Therefore true could be assigned to temp[key];

Actual behavior:
Error in function fn2

Type 'true' is not assignable to type 'K extends K ? true : false'.ts(2322)

I suppose type K extends K ? true : false should be automatically resolved to type true.

Playground Link:
Playground Link

I also test the same function with a concrete type and it works as expected. And even if I implement type R without conditional types (Q in example code), the bug still exists, so I guess there is nothing to do with conditional types, but mapped types and generic type;

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions