Enforcing the type of the indexed members of a Typescript object?

后端 未结 8 1718
旧时难觅i
旧时难觅i 2020-11-29 15:15

I would like to store a mapping of string -> string in a Typescript object, and enforce that all of the keys map to strings. For example:

var stuff = {};
st         


        
8条回答
  •  误落风尘
    2020-11-29 15:49

    interface AgeMap {
        [name: string]: number
    }
    
    const friendsAges: AgeMap = {
        "Sandy": 34,
        "Joe": 28,
        "Sarah": 30,
        "Michelle": "fifty", // ERROR! Type 'string' is not assignable to type 'number'.
    };
    

    Here, the interface AgeMap enforces keys as strings, and values as numbers. The keyword name can be any identifier and should be used to suggest the syntax of your interface/type.

    You can use a similar syntax to enforce that an object has a key for every entry in a union type:

    type DayOfTheWeek = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
    
    type ChoresMap = { [day in DayOfTheWeek]: string };
    
    const chores: ChoresMap = { // ERROR! Property 'saturday' is missing in type '...'
        "sunday": "do the dishes",
        "monday": "walk the dog",
        "tuesday": "water the plants",
        "wednesday": "take out the trash",
        "thursday": "clean your room",
        "friday": "mow the lawn",
    };
    

    You can, of course, make this a generic type as well!

    type DayOfTheWeek = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
    
    type DayOfTheWeekMap = { [day in DayOfTheWeek]: T };
    
    const chores: DayOfTheWeekMap = {
        "sunday": "do the dishes",
        "monday": "walk the dog",
        "tuesday": "water the plants",
        "wednesday": "take out the trash",
        "thursday": "clean your room",
        "friday": "mow the lawn",
        "saturday": "relax",
    };
    
    const workDays: DayOfTheWeekMap = {
        "sunday": false,
        "monday": true,
        "tuesday": true,
        "wednesday": true,
        "thursday": true,
        "friday": true,
        "saturday": false,
    };
    

    10.10.2018 update: Check out @dracstaxi's answer below - there's now a built-in type Record which does most of this for you.

    1.2.2020 update: I've entirely removed the pre-made mapping interfaces from my answer. @dracstaxi's answer makes them totally irrelevant. If you'd still like to use them, check the edit history.

提交回复
热议问题