microsoft / microsoft/TypeScript
incorrect result with conditional type and boolean
Open
@weswigham is already working on this.
Since Oct 12, 2020.
Needs Investigation
Rescheduled
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
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:
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.