microsoft / microsoft/TypeScript

Incorrect conditional type evaluation on transformed function type expressions

Open
#55,587 1 comment 0 reactions 1 assignee View on GitHub

@weswigham is already working on this.

Since Sep 1, 2023.

Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔎 Search Terms

"conditional type", "function type", "extends", "evaluation", "inference"

🕗 Version & Regression Information

This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play?ts=4.7.4#code/PTAEEFQUwDwFygOwCYGdQCEBQcCeAHKCUAXlAAoA3AQwBsBXKALlFTgCcBLRAcwEpSAPlCUA9p2Q4CRDKQo0GzUAHIAFlFq1RygSWFiJWKYVAAxSGVMAecIKwh5dRizZdeu-eMnGip2ZasMOwcqJyUAFgAmDxEvIwc4dVAAY1EAW3x6BGQRMPRqdiJUjIKoHNT2QuTaPB9QAHkAaTlzaHgkNDNZAH5QDkZQFgAzOlQoAG57MFBQAD1u+LBEolEuHm46NvxC1FROUUR8wtBEUTg6xvqWm2FYBBR0ayDQXv6iYdGJqZm5he+AFVUnHQnAytCgaSQcGocH2iFAyFEUHQpzgbSBACNOGjlqBtqIMeC0nV6lcyABxG5te6dSnPV7sAYfWhjSYOGbzIx4EzWf7UjqPRDCMjkAB04oKPFQLH+7GohyGqzSAAUCtQ0qgrKq5ZCEOxNf9BIIYgAlKBwejsRD-aRWQ1c6SgSl8u4CsxC0hYGba9XmqD6u23doPUDcIb+0A+jX8kP0RAAa1OAHdEABtAC6XpeFHFosl0tAsvlqEV7BVao1WorqGNQlAZotVpthEDWZYiCglH9DpMRYVSqjBuFoAA3qBU81uKB41BcKIhoX0yxmq6QzO5wuM9n-hP04NC7uY501BotMps1F9zvGnuAL6TOqmeFkHMS9hSljy3AZmJxxOiFNxiAA

💻 Code
// A extends B
type A = (value: string) => void
type B = (value: 'hello') => void

type FA = F<A>
// (value: string) => void

type FB = F<B>
// (value: 42) => void

// the computed values are compared correclty
type OK = FA extends FB ? true : false;
// return false

// the original expressions are not
type KO = F<A> extends F<B> ? true : false;
// return true

// This implementation does not exhibit the problem
type OO = G<A> extends G<B> ? true : false;
// return false

type F<T extends Fn> = (...args: TransformParams<Parameters<T>>) => ReturnType<T>

type G<T extends Fn> =
  Parameters<T> extends infer Params extends unknown[]
  ? (...args: TransformParams<Params>) => ReturnType<T>
  : never

type TransformParams<T> = { [K in keyof T]: K extends keyof [] ? T[K] : T[K] extends 'hello' ? 42 : T[K] };

type Fn =  (...args: any[]) => unknown;
🙁 Actual behavior

The comparison of the expressions F<A> and F<B> is incorrect and is not equivalent to the comparison of their results.

🙂 Expected behavior

F<A> extends F<B> should be false because it should evaluate to ((value: string) => void) extends ((value: 42) => void), and string and 42 are unrelated.

Additional information about the issue

Interestingly, G, which should behave the same as F, does not exhibit the problem.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.