1

I'm playing around with https://2ality.com/2020/06/computing-with-types.html#conditional-types to learn the type relationships in TypeScript.

Having defined the type function IsAssignableTo:

type IsAssignableTo<A, B> = A extends B ? true : false

I got the desired results like:

type MyGoodType1 = IsAssignableTo<42, Object>           // MyGoodType1 === true
type MyGoodType2 = IsAssignableTo<42, object>           // MyGoodType2 === false
type MyGoodType3 = IsAssignableTo<'foo', 'foo'|'bar'>   // MyGoodType3 === true

However, the result of reversing the parameters of the last expression:

type MyStrangeType = IsAssignableTo<'foo'|'bar', 'foo'> // MyStrangeType === boolean ???

is, to my surprise, neither literal true nor literal false (expecting it to be false), but a boolean?

My Questions are

  1. How assignability for union types works in TS? I've read SPEC's Assignment Compatibility and got no luck.
  2. How could the result of T1 extends T2 ? A : B become a union of A and B?

Complete Code in Playground

0

1 Answer 1

1

Conditional types acting on generic arguments become distributive when given union types, i.e.,

IsAssignableTo<'foo' | 'bar', 'foo'> 
    = IsAssignableTo<'foo', 'foo'> | IsAssignableTo<'bar', 'foo'>
    = true | false
    = boolean

You can avoid that by wrapping your generic type into a one-tuple. Since the conditional is now no longer applied to a union, no distribution occurs:

type IsAssignableTo<A, B> = [A] extends [B] ? true : false;

You can also find this information in the handbook.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.