Pocket Pokemon Type Evaluator Yes, I know there are already three pokemon type questions, but almost all submissions hardcode the whole chart in one way or other. I think it'd be nice to change the requirement a bit to encourage more shortcut-taking typically seen in decision problems.

Objective

Write a program/function/whatever that accepts the attacking type and the defending type(s), and output something that can be identified as the final multiplier.

As usual, you can see the pokemon type chart here. Also available as text form (copied from another question linked above and modified a bit):

                                            Attacking Type                              
                No  Fi  Fl  Po  Gr  Ro  Bu  Gh  St  Fr  Wa  Gr  El  Ps  Ic  Dr  Da  Fa
    Normal        1   2   1   1   1   1   1   0   1   1   1   1   1   1   1   1   1   1
    Fighting      1   1   2   1   1 0.5 0.5   1   1   1   1   1   1   2   1   1 0.5   2
D   Flying        1 0.5   1   1   0   2 0.5   1   1   1   1 0.5   2   1   2   1   1   1
e   Poison        1 0.5   1 0.5   2   1 0.5   1   1   1   1 0.5   1   2   1   1   1 0.5
f   Ground        1   1   1 0.5   1 0.5   1   1   1   1   2   2   0   1   2   1   1   1
e   Rock        0.5   2 0.5 0.5   2   1   1   1   2 0.5   2   2   1   1   1   1   1   1
n   Bug           1 0.5   2   1 0.5   2   1   1   1   2   1 0.5   1   1   1   1   1   1
d   Ghost         0   0   1 0.5   1   1 0.5   2   1   1   1   1   1   1   1   1   2   1
i   Steel       0.5   2 0.5   0   2 0.5 0.5   1 0.5   2   1 0.5   1 0.5 0.5 0.5   1 0.5
n   Fire          1   1   1   1   2   2 0.5   1 0.5 0.5   2 0.5   1   1 0.5   1   1 0.5
g   Water         1   1   1   1   1   1   1   1 0.5 0.5 0.5   2   2   1 0.5   1   1   1
    Grass         1   1   2   2 0.5   1   2   1   1   2 0.5 0.5 0.5   1   2   1   1   1
T   Electric      1   1 0.5   1   2   1   1   1 0.5   1   1   1 0.5   1   1   1   1   1
y   Psychic       1 0.5   1   1   1   1   2   2   1   1   1   1   1 0.5   1   1   2   1
p   Ice           1   2   1   1   1   2   1   1   2   2   1   1   1   1 0.5   1   1   1
e   Dragon        1   1   1   1   1   1   1   1   1 0.5 0.5 0.5 0.5   1   2   2   1   2
    Dark          1   2   1   1   1   1   2 0.5   1   1   1   1   1   0   1   1 0.5   2
    Fairy         1 0.5   1   2   1   1 0.5   1   2   1   1   1   1   1   1   0 0.5   1


You can choose to either accept one or two defending types (the final multiplier for two defending types is just the product of all individual defending types). Both types of submissions are allowed, as they will be in separate categories.

Rules

You can choose any methods of input in any form, structure or order (e.g ['fire',['water','rock']]/['fire',['rock']]/['fire','rock'], 'water,ice,ghost'/'water,ghost',dragondragonsteel/dragondragon).

The only requirement is that the types being inputted must be exactly their names and nothing else. Moreover, the types are required to be in one case only: so if you choose "psychic/Psychic/PSYCHIC", you must also use the same case for every other types (e.g "poison/Poison/POISON"). The available casing are: all lowercase, capital case and all uppercase.

You can output anything as long as different multipliers corresponds to one and only one output value.

There will not be two defensive types of the same type.

Standard loopholes are disallowed.

Shortest byte wins.
JavaScript (ES6), 270 246 221 bytes
Takes input in currying syntax (a)(d) where a is the attacking type as a string and d are the defending type(s) as an array of strings. The case doesn't matter.
Returns a standard multiplier as a float.

a=&gt;d=&gt;d.map(d=&gt;r*='0124'[&quot;ijfkj{jjnjjJ[kefjiZj[jxnjni^YnEW]vfeziiz]okjZmniV{oZvjhjnmj[zrfijij[yVzej[jjejjhujkmjZkZ[fjiuznjjz~zjfRjbkjy&quot;.charCodeAt((i=g(d)*18+g(a))/3)&gt;&gt;i%3*2&amp;3]/2,g=s=&gt;parseInt(s,36)*64%97%54%21%18,r=1)&amp;&amp;r

Try it online! or check the whole chart
How?
The base-36 interpretation \$N\$ of a given Pokemon type string is converted to a coordinate \$C\$ in \$[0..17]\$ using the following minimal perfect hash function:
$$C=((((N\times64)\bmod97)\bmod54)\bmod21)\bmod18$$
The chart is rearranged using the new coordinates and encoded as a single string with 6 bits of payload data per character, using ASCII codes in the range \$[64..127]\$.
There are 2 bits per cell, so the length of the string is \$(18\times18\times2)/6=108\$ characters.
For the curious, here is the code that encodes the string.