'Create an object that contains property names of another object

I am trying to create a TS validated utility that iterates over the first level properties of the object and returns a new one with its property name.

JS-wise it's quite straightforward, but I would appreciate a bit if you can help me a bit define a correct type structure. I've created a TS Playground link with the code example

P.S: Feel free to drop any suggestion on type refactor if you know a better way :-)



Solution 1:[1]

This is absolutely possible and simple with a mapped type:

type PropMap<T> = {
    [K in keyof T]: K;
};

And then we change the definition of the function to return this:

function createObjectKeys<T> (object: T): PropMap<T> {

Unfortunately a cast is required here:

    return keys as PropMap<T>;

But if you try it in the playground below you'll see that it produces the correct types:

Playground

Solution 2:[2]

You don't actually need to create any type helper for this, your object itself holds sufficient info to make the code snippet work

/* Types */
type ObjectWithStrings = {
    [index: string]: string
}

type InterfaceRecipeComponents = {
    information: boolean
    ingredients: boolean
    method: boolean
}

/* Logic */
function createObjectKeys<T1, _R = { [k in keyof T1 ]: k }> (object: T1): _R {
    const keys: ObjectWithStrings  =  {}

    Object.keys(object).forEach((propertyName) => {
        keys[propertyName] = propertyName
    })

    return keys as unknown as  _R
}


const recipeComponents: InterfaceRecipeComponents = {
    information: false,
    ingredients: true,
    method: true
}

export const recipeComponentsKeys = createObjectKeys(recipeComponents)

console.log(recipeComponentsKeys.test)

Code Playground

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2