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

Typescript create key constrained type for object literal with inferred number values

Let’s say we have object literal like:

export const SOURCE = {
    UNKNOWN: 'Unknown',
    WEB: 'Web',
    MOBILE: 'Mobile',
    ...
} as const;

and

export const OTHER_SOURCE = {
    UNKNOWN: 0,
    WEB: 1,
    MOBILE: 2, // values might be not sequential or incrementing at all 
    ...
} as const;
OTHER_SOURCE.UNKNOWN // inferred to 0  

How to constrain second object literal so it has keys from SOURCE but the values are still inferred as literals, not numbers like below:

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 ConstraintType = {
    [key in keyof typeof USER_SOURCE]: number; // how to infer (and possibly still force numbers) numeric values from the second object?
};
export const OTHER_SOURCE: ConstraintType = { ... } as const;
OTHER_SOURCE.UNKNOWN // inferred to number ]  

Thank you for help and clarifications.

>Solution :

If you specify the type of a variable, that is it’s final type, so as long as the expression on the right is assignable to it, everything is fine.

If you want to capture capture the types from the object literal assigned to OTHER_SOURCE but also constrain it to have the same properties, you can use a function

export const SOURCE = {
    UNKNOWN: 'Unknown',
    WEB: 'Web',
    MOBILE: 'Mobile',
} as const;

function makeSource<T extends Record<keyof typeof SOURCE, V>, V extends number>(o: T): Readonly<T> {
  return o
}
const OTHER_SOURCE = makeSource( {
    UNKNOWN: 0,
    WEB: 1,
    MOBILE: 2, // values might be not sequential or incrementing at all  
});


OTHER_SOURCE.UNKNOWN // 1

Playground Link

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