question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

incorrect result with conditional type and boolean

See original GitHub issue

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:

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:10 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
unionalcommented, Oct 12, 2020

@Constantiner btw, I like the clean up version of Not more then the one I have.

  If<
    Equal<X, true>,
    false,
    If<Equal<X, false>, true, boolean>
  >

I’ll update that in type-plus. Thanks! 👍

1reaction
unionalcommented, Oct 12, 2020

Um… I think that won’t work. The tricky thing about it is that A, B, X can be boolean and not just a concrete true or false. So your And will fail in those cases (your code is identical to A extends false ? false : B extends false ? false : true).

Your Not can be simplified to:

  If<
    Equal<X, true>,
    false,
    If<Equal<X, false>, true, boolean>
  >

Your Not and mine are the same because Equal<> takes care of the boolean union type correctly.

The OP code will still be wrong if we just change the Not and not And.

~Here are the tests for And and Not:`~

Read more comments on GitHub >

github_iconTop Results From Across the Web

Conditionals with if/else & Booleans | AP CSP (article)
The condition is a Boolean expression: an expression that evaluates to either true or false . Boolean values are another type of data...
Read more >
boolean[] in conditional types expands to true[] | false[]
The answer is probably a bit late but it works by infering the type argument if an array like this type MakeArray<T, V...
Read more >
Booleans & conditionals - Beautiful Racket
True is spelled #true or #t. False is spelled #false or #f. When used in a conditional expression, every value other than #false...
Read more >
Conditional Statements and Boolean values Have I ...
So by adding the boolean value false in the if ( false ) { } the if condtional statement is the reason why...
Read more >
9. Working with Booleans and Conditional Statements
There are only two possible Boolean values: false and true . Boolean values result when a Boolean expression is evaluated by C#. They...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found