Actually, you can't use types for this as such, as types can only be invoked at "build" time (or whatever name you want to give it). You can't manipulate or use a type in a script. You can say an object is of a certain type, but you couldn't peek into that type at run time and see attributes, etc.
You have two things to work out.
1) You need a place to store different attributes for different races.
2) You need a way to take those attributes and add them to the player object dynamically.
If you can live with a level of indirection for accessing the attributes, then I would place the different race attributes in to separate race objects and then simply store an attribute to the chosen race variable in the player.
<object name="HumanRace">
<race>human</race>
<maxhp type="int">50</maxhp>
</object>
<object name="FoxDemon">
<race>fox demon</race>
<maxhp type="int">75</maxhp>
</object>
choices = NewStringDictionary()
dictionary add (choices, HumanRace.race, "HumanRace")
dictionary add (choices, CatRace.race, "CatRace")
dictionary add (choices, DogRace.race, "DogRace")
dictionary add (choices, FoxRace.race, "FoxRace")
-- snipped --
msg ("What is your race?")
show menu ("I am ...", choices, false) {
player.race = GetObject(result)
msg ("I am " + player.race.race)
msg ("My maxhp is " + player.race.maxhp)
Note three things. First, you have to use objects, not types. If you had made them types, you would not be able to use them in your scripts (their names aren't accessible to scripts). Second, if you use a dictionary for the menu instead of a straight list (it supports both flavors), then you can pair up a string (e.g. "human") with your desired result (e.g. the HumanRace object). And third, in the above example, all the race variables are nested under a "race" attribute. That means that instead of using "player.maxhp", you'd have to use "player.race.maxhp". I don't consider that too bad of a deal. But if it is for you, read on...

If you really do need a way to set all the attributes directly onto the player, then life becomes harder. The main thing that's missing for what you want to do is a way to enumerate attributes on an object. So you couldn't, say, look through all the attributes of the chosen race object and copy them to the player. One solution is to do it all by hand:
player.race = race.race
player.maxhp = race.maxhp
...
Which I assume is what you wanted to avoid...
A solution to that is to set up a string list (once) of all the attributes you care about, and then use *that* to enumerate the race object. It's not 100% automatic as you do have to maintain the list, but it's, well, *automated*.
<type name="RaceBase">
<attributes type="list">race; maxhp; speed; dodge; str</attributes>
<type>
<object name="HumanRace">
<inherit name="RaceBase"/>
<race>human</race>
<maxhp type="int">50</maxhp>
--snipped--
</object>
<object name="CatRace">
<inherit name="RaceBase"/>
<race>cat</race>
<maxhp type="int">35</maxhp>
--snipped--
</object>
choices = NewStringDictionary()
dictionary add (choices, HumanRace.race, "HumanRace")
dictionary add (choices, CatRace.race, "CatRace")
dictionary add (choices, DogRace.race, "DogRace")
dictionary add (choices, FoxRace.race, "FoxRace")
-- snipped --
msg ("What is your race?")
show menu ("I am ...", choices, false) {
// Copy all the attributes, using the "attributes" string list as key.
race = GetObject(result)
foreach (attribute, race.attributes) {
set (player, attribute, GetAttribute(race, attribute))
}
msg ("I am a " + player.race)
msg ("My maxhp is " + player.maxhp)
You do have to set up the attributes list, but once you do that, the code handles the rest.
So those are three choices I can offer:
1) Use a nested "race" object attribute
2) Copy the attributes by hand
3) Set up a list of the attributes you want to copy.
Hope that helps!
(Note: the code above I just whacked in there. There might be a typo or two, so if you take it verbatim and it doesn't work straight off, it's me not you. Either ask for help, or work out the problem.

)