microsoft / microsoft/TypeScript

incorrect result with conditional type and boolean

Offen
#41,053 10 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@weswigham arbeitet bereits daran.

Seit 12.10.2020.

Needs Investigation Rescheduled
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

TypeScript Version: 4.0.2

Search Terms:

"conditional type" "boolean" "incorrect result"

Code

type HasKey<T, K> = K extends keyof T ? true : false
type SimpleNot<X extends boolean> = X extends true ? false : true
type SimpleAnd<A, B> = A extends true ? B extends true ? true : false : false
type IsDisjointSimple<A, B> = SimpleAnd<SimpleNot<HasKey<A, keyof B>>, SimpleNot<HasKey<B, keyof A>>>

type If<Cond extends boolean, Then, Else> = Cond extends true ? Then : Else
type Equal<A, B> =
  (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2)
  ? true : false
type And<A extends boolean, B extends boolean> = If<
  Equal<A, true>,
  B,
  If<
    Equal<B, true>,
    A,
    If<
      Equal<A, boolean>,
      If<Equal<B, boolean>, boolean, false>,
      false
    >
  >
>
type Not<X extends boolean> = If<
  Equal<X, boolean>,
  boolean,
  If<Equal<X, true>, false, true>
>
type IsDisjoint<A, B> = And<Not<HasKey<A, keyof B>>, Not<HasKey<B, keyof A>>>

type Foo = { a: 1 }
type Boo = { b: 1 }

// false - correct
type fooHasBooKeys = HasKey<Foo, keyof Boo>

// true - correct
type fooNoBooKeysSimple = SimpleNot<HasKey<Foo, keyof Boo>> 

// true - correct
type isFooBooDisjointSimpleRaw = And<SimpleNot<HasKey<Foo, keyof Boo>>, SimpleNot<HasKey<Boo, keyof Foo>>> 

// true - correct
type isFooBooDisjointSimple = IsDisjointSimple<Foo, Boo>

// true - correct
type fooNoBooKeys = Not<HasKey<Foo, keyof Boo>>

// true - correct
type booNoFooKeys = Not<HasKey<Boo, keyof Foo>>

// true - correct
type isFooBooDisjointRaw = And<Not<HasKey<Foo, keyof Boo>>, Not<HasKey<Boo, keyof Foo>>> 

// false - wrong
// this should be identical to `isFooBooDisjointRaw`.
// The type is exactly the same.
type isFooBooDisjoint = IsDisjoint<Foo, Boo> 

The type utilities HasKey, If, Equal, And, Not are unit tested in https://github.com/unional/type-plus/pull/71 and should be working as expected.

Playground Link:
playground

Related Issues:

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.