Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to reference the key of `Record<>` in the record value

Given the following MyKey type

type MyKey = 'alpha' | 'beta' | 'charlie' | 'delta'

I’d love to define a Record type where each key must be present AND each value must be a function that returns an object with name property that is the same as the key.

Here’s my best attempt

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

type MyRecords = Record<MyKey, () => {name: MyKey}>

const example: MyRecords = {
    'alpha': () => ({name: 'beta'}),
    'beta': () => ({name: 'beta'}),
    'charlie': () => ({name: 'beta'}),
    'delta': () => ({name: 'beta'}),
}

But the issue here is that all records are content to any MyKey (beta in this case) as the name value. I want to constrain it to

const example: MyRecords = {
    'alpha': () => ({name: 'alpha'}),
    'beta': () => ({name: 'beta'}),
    'charlie': () => ({name: 'charlie'}),
    'delta': () => ({name: 'delta'}),
}

typescript playground

>Solution :

You don’t want to use the Record<K, V> utility type here at all, as it does not represent a relationship between the specific key types and value types. If you use Record<K, V>, all properties will be of the same type.

Instead you should just write your own mapped type where you refer to the key type parameter inside the property type. Like this:

type MyRecords = { [K in MyKey]: () => { name: K } }
/* type MyRecords = {
    alpha: () => {
        name: "alpha";
    };
    beta: () => {
        name: "beta";
    };
    charlie: () => {
        name: "charlie";
    };
    delta: () => {
        name: "delta";
    };
} */

That’s the type you want, and it behaves how you want with your example:

const example: MyRecords = {
    'alpha': () => ({ name: 'beta' }), // error
    'beta': () => ({ name: 'beta' }), // okay
    'charlie': () => ({ name: 'beta' }), // error
    'delta': () => ({ name: 'beta' }), // error
}

Playground link to code

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading