microsoft / microsoft/TypeScript

Conditional (using extends) parametrised type inference seems to be inconsistent

Open
#59,700 2 comments 0 reactions 1 assignee View on GitHub

@ahejlsberg is already working on this.

Since Aug 30, 2024.

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

Description

🔎 Search Terms

repo:microsoft/inconsistent typing with extends and parametrised types
repo:microsoft/TypeScript inconsistent typing with extends
repo:microsoft/TypeScript inconsistent conditional typing

🕗 Version & Regression Information
  • This is the behavior in every version I tried, and I reviewed all the FAQ for entries.
⏯ Playground Link

https://www.typescriptlang.org/play/?#code/MYGwhgzhAEDCIFcB2BrAPAOWgUwB4BdskATGCfAJwEskBzAPmgG8BfAKFEhgGUAHbYFTAh4ydFjyESZSjQY4CRUnESpMjJm2jQI-QcIBiVbCGLQAvNADkAMzEBPG8dNWA3G3Zt89-tD4ChEVUUAFFFaVFUCz89QMj0MCR7RkklGHi0ROToAH5oSgRsaAAuaBthCGxXaAB6GvyKQoA6Lx8i+LCpUn99ILFojKyU8OUeuODMpMY8gqLS8pBK6rqG5rY2PF4Aewp8fLa-LYBbbAyAFQUumCskHaPhK2gAH2tdAIeAGmgJEZlqOkYlguqWk1luFHuICsWlyKjE6hhpWBv1esQeMLyY2EGQw9ER0CQ2AAbtgKO5Wr4sSBOmkMHdhNErG9eo8QcobvSobDZiUyhUqrV6gtKi1vL46RDhDTpFTGeDIayUUy0VyZo05nzFgKVsLsC02CsAKqVaBbGz7XwAC1JRXwW2gACMisBjrwwPgqA6QEUAO5UfCW6C0IikqjAaBuihgI4QFqbHZ7MVFAAKAEY0MirmDOY8Xsr3lDAcwYaAxKVuMdThMzl9bFstlZ6O4WOSk9A0-KGZY02gOZLC8t6m2O5zokxoKXUKUMgAiGz1mdN6DsYep5mBaI9-MspcrVfrrvMCfBcsq2fzraL6org5pqnS0gSyGbtcqy5pdupzsgbnq3m6wdVmwCkU1TJ9hAAES2bAIDpfAHwgWVuy-Uc2RgNMDx-NVCn-flAN1EDP3vX5wJAOkfQMfkX17TDG3fUEt2-OjsI1ADBU1E0gA

💻 Code
class Clunk<N extends string> {}
class SpecialClunk<N extends string> extends Clunk<N> {
  specialField = 'funkyfield';
}

type SpecialClunkExtendsClunk = SpecialClunk<any> extends Clunk<any> ? true : false; // true.
type ClunkExtendsSpecialClunk = Clunk<any> extends SpecialClunk<any> ? true : false; // true.

export type SomeClunk<T extends 'normal' | 'special', N extends string> = T extends 'normal'
  ? Clunk<N>
  : T extends 'special'
  ? SpecialClunk<N>
  : never;

type SpecialExtendsNormal = 'special' extends 'normal' ? true : false; // false.
type NormalExtendsSpecial = 'normal' extends 'special' ? true : false; // false.

// Use of type here to be compatible with generic params.
export type P1<T extends 'normal' | 'special'> = {
  clunk: SomeClunk<T, 'foo'>;
};

type P1normal = P1<'normal'>; // type P1normal = { clunk: Clunk<"foo">; }
type P1special = P1<'special'>; // type P1special = { clunk: SpecialClunk<"foo">; }
type P1NormalDoesNotExtendsSpecial = P1normal extends P1special ? true : false; // false

type P1SpecialExtendsNormal = P1special extends P1normal ? true : false; // true

// Below is false, but expected to be true, like P1SpecialExtendsNormal *** BUG?
type P1SpecialExtendsNormalNowFalse = P1<'special'> extends P1<'normal'> ? true : false; // false 
🙁 Actual behavior

P1SpecialExtendsNormal is true
P1SpecialExtendsNormalNowFalse is false

🙂 Expected behavior

P1SpecialExtendsNormal is true
P1SpecialExtendsNormalNowFalse is true

Additional information about the issue

I can't tell if this might be related to https://github.com/microsoft/TypeScript/issues/44945

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.