What's assignable to what?
Python 3, 177 bytes

c is a dictionary of the parents of each type, a and b are the two expression to check. Types are represented by strings, while intersects and unions are represented by lists with of expressions, with the first element set to 0for intersect and 1 for union

Returns 0 if they are not assignable to each other, 1 if a is assignable to b, 2 if b is assignable to a and 3 if both are assignable to each other



lambda c,a,b:y(a,b,c)+2*y(b,a,c)
y=lambda a,b,c:(b in c[a]or a==b if b[0]in c else[all,any][b[0]](y(a,x,c)for x in b[1:]))if a[0]in c else[any,all][a[0]](y(x,b,c)for x in a[1:])


Try it online!