Skip to content

Probable bug: Functional properties don't get inferred with circular type parameter constraints like T extends M<T> #40439

Open
@devanshj

Description

@devanshj

TypeScript Version:
4.0.2

Search Terms:
Circular type parameter constraint, functional property inference, function parameter inference, function argument inference

Code:

declare const m: <T extends M<T>>(m: T) => T
type M<Self, K = Exclude<keyof Self, "k" | "t">> =
  { a?: number
  , b?: number
  , c?: number
  , d?: number
  , k?: K
  , t?: (k: K) => void
  }

// :)
// Case 1
m({
  a: 1,
  b: 2,
  k: "a"
})

// :)
// Case 2
m({
  a: 1,
  b: "x", // expected error
  k: "c" // expected error
})

// :(
// Case 3
m({ // type parameter becomes `unknown` (probably because t's first parameter is `any` initially kinda?)
  a: 1,
  b: 2,
  k: "a", 
  t: k => {} // k is inferred as `never` (instead of `"a" | "b"`)
})

// :|
// Case 4
m({
  a: 1,
  b: 2,
  k: "a", 
  t: (k: "a" | "b") => {} // have to explicitly type `k` which could have been inferred :(
})

Expected behavior:
The parameter k of t should be inferred as "a" | "b". As property k already gets inferred in Case 1 & 2, so why not the k parameter of t

Actual behavior:
The parameter of t is inferred as never and T in inferred as unknown. I assume first T gets resolved to unknown as t is initially inferred as (k: any) => void which does not satisfy the constraint of m.

Playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions