简体   繁体   中英

Use keys of an object as union-type

I've got a object (let it be frozen so typescript may handle its keys better):

const obj = Object.freeze({
    'hello': 64,
    'world': 20
}) as {[key: string]: number};

Now I have a function where the user can pick values by their keys:

const pick = (keys: Array<string>): Array<number> => {
    const values = [];

    for (const key of keys) {

        // Check if object contains property-key
        if (!(key in obj)) {
            throw new Error(`There's no such key: ${key}`);
        }

        values.push(obj[key]);
    }

    return values;
};

That's looking good so far and works flawlessly during runtime where I check if the user passed any invalid keys. But how can I tell TS that only keys from obj can be used?

I could do Array<'hello' | 'world'> Array<'hello' | 'world'> but I'd need to update it any time I add new properties to obj which is kinda annoying.

Related questions but they all seem to use types whereas I only have a object (which can be frozen if that helps):

  1. Make union type of objects from type keys (He got a type, I'm with a object)
  2. get union type of object keys filtered by type of object value (Basically the same as 1. but he wants the type whereas I'm trying to build a type out of my object)
  3. Get keys of union of objects in TypeScript (Looks good but he also got a type...)
const obj = Object.freeze({
    'hello': 64,
    'world': 20
});

const pick = (keys: Array<keyof typeof obj>) {...}

As you can see I have removed as {[key: string]: number}; as it was widening the type, where you wanted to have it strict.

Next things is Array<keyof typeof obj> I declare here that I accept as argument only array of keys from type of obj .

Array<keyof typeof obj> evaluates dynamically into ("hello" | "world")[] , fortunately as you wanted it will reflect every change in original obj

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM